指向变量vs数组的外部指针

Jan*_*Jan 3 c arrays pointers extern

我知道这个话题已经解决过几次了,但是我还是不明白。

参考http://c-faq.com/aryptr/aryptr2.html

char a[] = "hello";
char *p = "world";
Run Code Online (Sandbox Code Playgroud)

创建一个数组“ a”。该变量只是第一个内存地址的地址的标签。p是一个变量(==另一个内存地址的标签),包含第一个字符的地址(w-可能在内存中的其他位置)。

我不明白的是该主题的示例(谢谢!): 使用extern将数组与指针链接

extern1.c

extern int *array;
int test();

int main(int argc, char *argv[])
{
    printf ("in main: array address = %x\n", array);
    test();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

extern2.c

int array[10] = {1, 2, 3};

int test()
{
    printf ("in test: array address = %x\n", array);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

为什么指针指针变量“ extern int * array”(==内存地址的标签,包含另一个地址)在extern1中已经包含array [0]的内容?

有什么区别

int array[10] = {1, 2, 3};
int *ptrArrWorking = array; // == &array[0];
Run Code Online (Sandbox Code Playgroud)

?在外部情况下,它将类似于

int array[10] = {1, 2, 3};
int *ptrArrNotWorking = array[0]; 
Run Code Online (Sandbox Code Playgroud)

编辑:更明确地说,让我们将上面的示例解释为

int array[10] = {1, 2, 3};
int *ptrArrNotWorking = (int *)array[0]; 
Run Code Online (Sandbox Code Playgroud)

因此,这模拟了在外部示例中可以看到的相同行为。

间接隐藏在哪里?

非常感谢。

Que*_*tin 5

您已经在中定义了extern2.c一个名为的对象array

int array[10] = {1, 2, 3};
Run Code Online (Sandbox Code Playgroud)

这是一个包含十秒int的连续内存段。将其传递给printfin时test,它会衰减为指向其第一个元素的指针-这就是将数组传递给函数的方式。因此,printf输出first的地址int

extern1.c中,您在array再次声明时撒谎:

extern int *array;
Run Code Online (Sandbox Code Playgroud)

假装这array是一个指针,一个保存其他内容地址的对象。这种不匹配使程序“格式不正确,无需诊断”。这是“严重损坏”的标准说法-从那时起,就不再需要程序是编译还是运行时实际执行了什么操作。

实际上,该破损声明之后的代码确实将被array视为指针。因此,当您传递array给时printf,它将从数组的开头砍掉几个字节(根据您的平台,通常为4或8个字节),然后大喊“你去了,这里是指针”,并将其提供给printf

当然,它实际上不是有效的指针,但是前几个ints的位array填充在一起,所以您看到的是胡说八道。