c語言中數組的地址
Ⅰ c語言數組首地址相關問題!!
若a是一維數組名,我們知道*a就是a[0],就是*(arr+0)。因為a是數組的首地址,*a就是取首地址所指元素,就是數組的第一個元素。
同樣的道理,a是二維數組名時,*a也是取a的第一個元素,但是此時a所指的元素是一個一維數組,所以,實際上a所指元素是一維數組的首地址。
二維數組a,a是數組地址,指向行;有一個等價關系 a[i]=*(a+i)
a[i]指向列,&a[i]又指向行。
你可以將*和&理解為相反的操作:
a指向行,*(a+i)指向列,*(*(a+i)+j)等價於a[i][j];
就按a[3][4]這個例子來看:3行4列數組a可以理解為a[0],a[1],a[2]這三個一維數組
a[0][0] a[0][1] a[0][2] a[0][3]//第一行a[0][]
a[1][0] a[1][1] a[1][2] a[1][3]//第二行a[1][]
a[2][0] a[2][1] a[2][2] a[2][3]//第三行a[2][]
(數組含有4個元素)構成的二維數組,*a就是a[0],而a[0]就是第0行的首地址,也就是第一個數組的首地址。*(a+i)就是a[i],就是第i行的首地址。
如果現在定義a是字元型數組,輸出*a(也就是第一行的首地址)為0000,再輸出*(a+1)就是0004,而不是0001,就可以說明a是指向一維數組的指針。
Ⅱ 關於C語言數組的地址的疑問
當你寫int a[5]時,編譯器會分配sizeof(int) * 5的連續內存空間存放數組元素。數組名只是個常量,不佔任何存儲空間,它用名字a表示。打開反匯編看看,凡是用到數組名的地方都是都是直接寫的地址值,而不是像變數那樣通過訪問一個內存地址獲得數值,也就是說就是個立即數。
C的語法中有些東西可以在機器的層面上解釋,有些要在編譯器的層面上解釋。a這個數組名就要在編譯器的層面上解釋,編譯器把數組名和數組地址當成一個東西,它與變數名是指變數的值而不是地址不同。沒有為什麼,編譯器就是這么對待數組名的,就像字元串變數名指的就是首字元地址一樣,這是個規定。如果非要說為什麼,那就是將a當作數組內容沒有意義,例如,把a當作實參傳入函數,只是傳的數組地址,效率高,如果把a當作數組內容看待,那就意味著要把數組內容復制一份再傳到函數裡面了。
a和&a確實是一個值,因為a本身就是個常數沒有地址,編譯器並沒有將&a當作錯誤處理,而是友好的將其翻譯成a了。由於a是常數,你也不能給a再賦值了,而你寫a=b也沒問題,編譯器還是會友好的通過,只是a的值並沒有被改編而已。
你之所以會問a為什麼等於&a的原因是你把「名字」和「變數」搞混了,對變數來說&變數是指變數的地址,而數組名本身是個名字不是變數,因此它也不能被賦值,你可以翻翻所有的C語言書沒有將a稱作數組變數的,它只是個數組名,真正的數組變數(其實稱作數組指針)這么定義:int (*b)[5]; 你可以把a賦給b,通過(*b)[1]訪問數組元素。看,真正的數組變數訪問數組元素的方式都和數組名不同。
Ⅲ C語言中如何指定數組的首地址在指定的地址
據我所知,創建數組需要2個參數,1是地址,2是分配空間。空間分配是不能重復的,也就是說創建2個數組,這兩個數組是不可能重合的,為了防止這種事情出現,所以不能指定地址。而是編譯器自動分配,不能人為。
但是可以省去分配空間這個步驟,而是只創建地址,這就是指針的概念。比如int a[12],你若是想創建另一個代替a[12],可以int *p=a;這樣,p的值就是a數組的首地址了。int *p =(int*)0x80000;意思就是p[0]的地址是0x80000,創建的時候要確定(int*)0x80000已經分配過了,可以使用了,不然就相當於野指針,容易出錯。
Ⅳ C語言中的二維數組里a+1和*(a+1)為什麼都是地址
在C語言中,二維數組由多個一維數組構成,數組名a指向第一個一維數組的首地址,仍為地址。表達式a+1中的a是二級指針,指向數組a[0]的一維數組(表示行),1表示行移動1位,因此a+1表示的是1行0列的地址。
而在*(a+1)中,a同樣是二級指針,其值為指向一維數組的一級指針,即二維數組中的行。一級指針指向的一維數組只能通過行向下移動一位,所以*(a+1)就是第一行的首地址,也就是二維數組中第一行零列的地址。
舉例來說,如果有一個二維數組A[3][4],按「行優先順序」存儲,其首元素A[0][0]的地址計算公式為:
LOC(A[0][0]) = LOC(A[0][0]) + ((0 - 0) * 4 + (0 - 0)) * t = LOC(A[0][0])
而A[1][0]的地址計算為:
LOC(A[1][0]) = LOC(A[0][0]) + ((1 - 0) * 4 + (0 - 0)) * t = LOC(A[0][0]) + 4 * t
如果按「列優先順序」存儲,則A[0][0]的地址計算公式為:
LOC(A[0][0]) = LOC(A[0][0]) + ((0 - 0) * 3 + (0 - 0)) * t = LOC(A[0][0])
A[0][1]的地址計算為:
LOC(A[0][1]) = LOC(A[0][0]) + ((0 - 0) * 3 + (1 - 0)) * t = LOC(A[0][0]) + t
存放該數組至少需要的單元數為(m-p+1) * (n-q+1) * t 個位元組,其中m和n分別為數組的行數和列數,p和q為數組的起始下標,t為每個元素佔用的位元組數。
綜上所述,a+1和*(a+1)在C語言中都指向二維數組的特定地址,但具體指向的地址不同,前者指向的是行的移動,後者指向的是行首地址。
(4)c語言中數組的地址擴展閱讀:對於二維數組A[m][n],這是一個m行n列的二維數組。設a[p][q]為A的第一個元素,即二維數組的行下標從p到m+p,列下標從q到n+q。按「行優先順序」存儲時,元素a[i][j]的地址計算為:
LOC(a[i][j]) = LOC(a[p][q]) + ((i - p) * n + (j - q)) * t
按「列優先順序」存儲時,地址計算為:
LOC(a[i][j]) = LOC(a[p][q]) + ((j - q) * m + (i - p)) * t
存放該數組至少需要的單元數為(m-p+1) * (n-q+1) * t 個位元組,其中m和n分別為數組的行數和列數,p和q為數組的起始下標,t為每個元素佔用的位元組數。
Ⅳ C語言中,數組在內存中佔一片連續的存儲區,由什麼來代替它的首地址
C語言中規定,數組名就代表了該數組的首地址。
整個數組是以首地址開頭的一塊連續的內存單元。如有字元數組char c[10]。設數組c的首地址為2000,也就是說c[0]單元地址為2000。則數組名c就代表這個首地址。
因此在c前面不能再加地址運算符&。如寫作scanf("%s",&c);則是錯誤的。在執行函數printf("%s",c) 時,按數組名c找到首地址,然後逐個輸出數組中各個字元直到遇到字元串終止標志'