簡體   English   中英

指向數組第一個元素的指針的地址?

[英]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字節的數組。 沒有一個好地方可以將指針存放在數組的第一個元素上。

於是他擺脫了它。 他沒有為指針留出存儲空間來指向數組第一個元素,而是設計了這種語言,以便可以從數組表達式本身計算數組的位置。 因此,本文開頭的規則。


1. %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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM