天天看點

一些頭疼的事(day7)

實操了一些經典的代碼題目,發現以下問題:

1)int型與float型在記憶體的位元組裡中是如何存儲的?

用int型變量接收float型會出現很奇怪的現象。

2)數組是什麼?數組名和數組元素又是如何存儲在記憶體裡的?為什麼數組名可以當作指針使用?

數組是一個整體,它的記憶體是連續的;也就是說,數組元素之間是互相挨着的,彼此之間沒有一點點縫隙。

一些頭疼的事(day7)

「數組記憶體是連續的」這一點很重要。連續的記憶體為指針操作(通過指針來通路數組元素)和記憶體處理(整塊記憶體的複制、寫入等)提供了便利,這使得數組可以作為緩存(臨時存儲資料的一塊記憶體)使用。​

這裡産生的疑問分别為:

1)聲明一種數組類型(如int型)時,系統向記憶體申請了一塊什麼樣的儲存區域?

2)數組名是否跟指針變量一樣,存儲在同一個友善調用的記憶體區域?

3)數組内的元素既然是連續存儲的,其具體的以位元組方式存儲的格式又是什麼樣的?為什麼會自動生成下标?

3)c語言中的函數往往是直接操作變量的存儲位址和儲存位元組,這與python這種語言,實踐起來困難太多。

以scanf函數為例:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>


int main()
{

char a[] = "abc";
char b[20] = "#############"; printf("%s\n", b);
strcpy(b, a);
printf("%s\n", b);

  return 0;
  }      

這個過程很簡單,scanf函數會直接複制a中的字元串内容(含終止符\0),是以在執行完scanf函數後,b變量在存儲中的實際值為“abc\0########”,但在列印時,讀取到終止符後讀取便停止了,是以列印值為“abc”。

而在初讀這個函數時,我寫的錯誤代碼如下:

int main()

{

  char a = "abc";

  char b = "#############";

  printf("%s\n", b);

  strcpy(&b, &a);

  printf("%s\n", b);



  return 0;      

以上代碼問題很多:

如char型實際上就是int型,産生的疑問如下:

1)為何要設定數組儲存字元串資訊?

2)直接采用整數型的位址執行scanf函數為什麼行不通而用數組名的形式卻行得通?在操作層面上數組名與指針不是同級别嗎?

總結:以上問題歸根結底還是數組與記憶體的問題,涉及到底層的一些尚不清楚的原理。

當字元型數組存儲了字元串,其實其字元型數組的内部的各個元素,存儲的其實是每個字元串的首元素的位址,即其每個字元串的首個字元的位址,而其每個字元串又開辟了另外一個空間取存儲其資料内容。等于說,若你使用了字元型指針資料存儲了x個字元串,就相當于系統其實開辟了另外x個字元數組用于存儲這x個字元串,而這字元型指針數組,存儲的是x個字元型數組的首元素位址,由于字元型數組有着可以利用%s格式聲明符達到整體輸出的特點,是以即使字元型指針數組的内部存儲的隻是每個字元型數組的首元素位址,也可以利用其特性将其整體進行輸出,達到存儲字元串的效果。

但是若是指針數組存儲的為其他類型的資料,如整型資料,其無整體輸入輸出的特點,是以其相關的通路也隻能是單個輸入,單個輸出。