为什么数组的第一个元素等于数组?C

jia*_*u81 1 c arrays pointers

例如,假设您有一个数组 a 和一个指针 p。事情是这样的。

void main() {
    int a[10];
    int *p;
    for(i = 0;i <=10;i++)
        a[i] = (i + 1) * 2;
    p = &a[0];
    printf("%d",a[4]);
    printf("%d",p[4]);
}
Run Code Online (Sandbox Code Playgroud)

他们如何平等?

Ach*_*hal 5

为什么数组的第一个元素等于数组?。假设您有一个像这样的整数数组,int arr[5];根据您的问题标题

  • 数组的第一个元素是andarr[0]的值arr[0]
  • array表示arrarrnames 表示数组的基地址。所以arrarr[0]并不相同。arr是基地址 &arr[0]是值。

对于您的特定情况,整数数组a如下所示,数组的所有元素都存储在连续的内存位置中。假设数组基地址是0x100(某个内存位置)

 a[0]   a[1]  a[2]  a[3]  ........................................ a[9]
  ------------------------------------------------------------------------
 |  2  |  4  |  6  |  8  |  10  |  12  |  14  |  16  |  18  |  20  | 22  |
  ------------------------------------------------------------------------
0x100   0x104  0x108 ..                                         ..    
 a
LSB                                                                   MSB
Run Code Online (Sandbox Code Playgroud)

所以这里的a意思是0x100,假设基地址a0x100。现在当你这样做时

p = &a[0]; /* here you are setting p to point to one of the places in the array a and that is a[0] */ 
Run Code Online (Sandbox Code Playgroud)

这里p指向iefirst的元素,如下所示a0x100

       a[0]   a[1]  a[2]  a[3]  ........................................ a[9]
      ------------------------------------------------------------------------
     |  2  |  4  |  6  |  8  |  10  |  12  |  14  |  16  |  18  |  20  | 22  |
      ------------------------------------------------------------------------
    0x100   0x104  0x108  0x112 0x116..                                         ..    
     a
     |
     p   
Run Code Online (Sandbox Code Playgroud)

现在,当您打印a[4]它时10,它会像预期的那样打印出来,并且它会像下面一样扩展

a[4] = *(a + 4) /* here you can say that array name a is converted to a pointer to its first element */
     = *(0x100 + 4*4 ) /* multiplied by 4 ? bcz a is int array & each element size is 4 byte */
     = *(0x116) /* value at 0x116 memory location */
     = 10
Run Code Online (Sandbox Code Playgroud)

当你打印时p[4]它会像下面一样展开

p[4] = *(p + 4)
     = *(0x100 + 4*4) /*multiplied by 4 because int pointer increments by 4 bytes*/
     = *(0x116) ? /* it prints value at 0x116 location which 10 */
     = 10
Run Code Online (Sandbox Code Playgroud)

此外,在为 for 中的数组元素赋值时loop,您试图访问a[10]超出边界并导致未定义的行为。在下面的代码块中,条件部分应该i<10代替i<=10您声明的内容a[10],并且数组索引从 开始zero

for(i = 0;i <=10;i++) {  /* make it i<10 */
        a[i] = (i + 1) * 2;
}
Run Code Online (Sandbox Code Playgroud)

最后void main() { /* code */ }是不好的做法,它不符合 C 标准规范。int main(void) { }按照 C 标准草案中的规定使用n1256

5.1.2.2.1 程序启动

1 程序启动时调用的函数名为main。该实现没有声明该函数的原型。它应定义为返回类型 int 并且不带参数:

int main(void) { /* ... */ }

或带有两个参数(此处称为 argc 和 argv,尽管可以使用任何名称,因为它们对于声明它们的函数来说是本地的):

int main(int argc, char *argv[]) { /* ... */ }

或等价物;9) 或以某种其他实现定义的方式。