[英]Address of a pointer to first element of an array?
我是一個由指向數組開頭的指針在內存中的位置所迷惑的小人物。 據我了解,數組和指針可以使用相同的功能,例如*,&和[]。 因此,如果我創建一個char數組,我會理解:buffer ==&buffer [0]。
因此,不帶括號的arrayname就像一個指針,其中包含數組第一個條目的地址,對嗎?
但是,當我嘗試找出指針的地址(存儲&buffer [0]的地址)時,會給我與指針(&arrayname [0])中存儲的值相同的值。 怎么可能? 虛擬ram中的同一地址如何包含一個地址和buffer [0]的值(在下面的代碼中等於“ H”)?
#include <stdio.h>
#include <windows.h>
void main() {
char buffer[] = "Hello";
printf("Address buffer: %d\n", &buffer);
printf("Value buffer: %d\n", buffer);
printf("Address buffer[0]: %d\n", &buffer[0]);
printf("Value buffer[0]: %c\n", buffer[0]);
printf("Address buffer[1]: %d\n", &buffer[1]);
system("pause");
}
所以基本上我對第一個輸出感到困惑。 它不應該與第二個有所不同嗎? 非常感謝您的解釋...
問候
除非它是sizeof
或一元&
運算符的操作數,或者是用於在聲明中初始化另一個數組的字符串文字,否則類型為“ T
N元素數組”的表達式將被轉換(“ decay”)為類型為“指向T
指針”的表達式,該表達式的值將是數組第一個元素的地址。
假設以下代碼:
char buffer[] = "Hello";
...
printf( "%s\n", buffer );
在對printf
的調用中,表達式buffer
類型為“ 6-元素數組的char
”; 由於它不是sizeof
或一元&
運算符的操作數,也不是用於初始化聲明中的另一個數組,因此該表達式將轉換(“衰減”)為“ pointer to char
”類型的表達式( char *
) ,表達式的值是數組中第一個元素的地址。
現在,將printf
調用更改為
printf( "%p", (void *) &buffer );
這次, buffer
是一元&
運算符的操作數; 不會自動進行類型為“ pointer to char
”的轉換。 相反,表達式&buffer
的類型是“指向char
6元素數組的指針”,或者char (*)[6]
1 (括號很重要)。
這兩個表達式產生相同的值 -數組的地址與數組的第一個元素的地址相同-但兩個表達式的類型不同。 這很重要; char *
和char (*)[6]
不可互換。
那么,為什么這種時髦的轉換魔術首先存在呢?
當丹尼斯·里奇(Dennis Ritchie)最初設計C時,他的設計是基於名為B的早期語言進行的。 在B中分配數組時,如下所示:
auto arr[N];
編譯器將為數組內容留出N個元素,以及一個存儲到數組第一個元素的偏移量的附加單元(基本上是一個指針值,但沒有任何類型的語義; B是一種“無類型”語言) 。 這個額外的單元格將綁定到變量arr
,從而為您提供以下內容:
+---+
arr: | | --+
+---+ |
... |
+---+ |
arr[0]: | | <-+
+---+
arr[1]: | |
+---+
arr[2]: | |
+---+
... ...
+---+
arr[N-1]: | |
+---+
Ritchie最初保留了這些語義,但是當他開始向C添加結構類型時遇到了問題。 IOW,給定類似
struct {
int inode;
char name[14];
};
他想要一個2字節的整數,緊隨其后的是14字節的數組。 沒有一個好地方可以將指針存放在數組的第一個元素上。
於是他擺脫了它。 他沒有為指針留出存儲空間來指向數組第一個元素,而是設計了這種語言,以便可以從數組表達式本身計算數組的位置。 因此,本文開頭的規則。
%p
轉換說明符期望將void *
表達式作為其對應的參數,因此將其強制轉換。
這是錯誤的:
printf("Address buffer: %d\n", &buffer);
printf("Value buffer: %d\n", buffer);
假設數組為指針的正確代碼為:
printf("Address buffer: %p\n", (void*) buffer);
printf("Value buffer: %d\n", *buffer);
您可以將array[x]
為*(array + x)
,這意味着:
讀取數組+元素大小的x指向的內存區域
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.