指向变量与数组的外部指针
Extern pointer to variable vs array
我知道这个话题已经讨论过几次了,但我还是不明白。
参考http://c-faq.com/aryptr/aryptr2.html
char a[] = "hello";
char *p = "world";
创建数组 "a"。该变量只是第一个内存地址的地址的标签。
p 是一个变量(== 另一个内存地址的标签),包含第一个字符的地址(w - 可能在内存中的其他地方)。
我不明白的是这个主题的例子(谢谢!):
using extern to link array with pointer :
extern1.c
extern int *array;
int test();
int main(int argc, char *argv[])
{
printf ("in main: array address = %x\n", array);
test();
return 0;
}
extern2.c
int array[10] = {1, 2, 3};
int test()
{
printf ("in test: array address = %x\n", array);
return 0;
}
为什么extern1中的指针变量"extern int *array"(==内存地址的标号,包含另外一个地址)已经包含数组[0]的内容了?
和
有什么区别
int array[10] = {1, 2, 3};
int *ptrArrWorking = array; // == &array[0];
?
在外部情况下,它会像
int array[10] = {1, 2, 3};
int *ptrArrNotWorking = array[0];
编辑:更明确地说,我们将上面的示例解释为
int array[10] = {1, 2, 3};
int *ptrArrNotWorking = (int *)array[0];
所以这模拟了在外部示例中可以看到的相同行为。
间接隐藏在哪里?
非常感谢。
仅使用 extern
declares a variable, but not defines it。
实际上这意味着 array
变量(在 extern1.c 中声明为 extern
)只是实际变量 array
定义在 extern2.c
您在 extern2.c
中定义了一个名为 array
:
的对象
int array[10] = {1, 2, 3};
这是包含十个 int
的连续内存段。在将它传递给 test
中的 printf
后,它会衰减为指向其第一个元素的指针——这就是数组传递给函数的方式。因此,printf
打印第一个 int
.
的地址
然而,在 extern1.c
中,您在再次声明 array
时撒谎:
extern int *array;
这假装 array
是一个指针,一个保存其他对象地址的对象。这种不匹配导致程序 "ill-formed, no diagnostic required"。那是 "badly broken" 的标准——从那时起,就不再要求程序是否编译,或者它在运行时实际做了什么。
在实践中,该损坏声明之后的代码确实会将 array
视为指针。因此,当您将 array
传递给 printf
时,它会从数组的开头切掉一些字节(通常是 4 或 8,具体取决于您的平台),大喊 "there you go, here's the pointer" 并给出至 printf
.
当然,它实际上不是一个有效的指针,而是array
的前几个int
的比特位塞在一起,所以你看到的是废话。
creates an array "a". The variable is only a label of the address of the first memory address.
不是,a
是整个数组hello[=13=]
。每当在表达式中使用标识符 a
时,数组 "decays" 就会成为指向其第一个元素的指针。也就是说,在使用 a
的表达式中,您将得到一个指向字母 'h'
.
的临时 char*
可以这样想:数组就是通往罗马的道路。您询问编译器 "where is the road to Rome, I need to access it",然后它会帮助您设置一个临时路标。这并不意味着通往罗马的道路成为路标。这也不意味着路标本身就是通往罗马的道路。同样,通往罗马的道路不会因为你在上面行驶(访问它)而成为路标。
Why does the pointer variable "extern int *array" (== a label of memory address, containing an other address) in extern1 already contain the content of array[0]?
没有。您不能编写 extern int* array
并期望获得指向分配在别处的数组 int array[10]
中第一项的指针。因为数组不是指针,指针也不是数组。
反汇编示例中发生的事情是代码调用未定义的行为(错误),程序员向编译器撒谎并说 "what's stored here is actually a pointer, trust me" 即使那里没有指针,而是一个整数。
因此,正如在该特定系统上发生的那样,您将指针的地址设置为 1
。不是 pointed-at 数据。这不是你可以依靠的;如果指针和整数在给定系统上具有不同的大小或表示,代码也可能会崩溃。
打个比方,你的编译器就是driver,CPU的程序计数器就是汽车。用 extern int *array
你告诉编译器 "that thing over there a road sign!",指的是实际的道路。编译器然后盲目地按照你告诉它的去做,并尝试从沥青中解释一些方向,然后让汽车跟随它,然后它跑到荒野中,很可能撞毁并且肯定永远不会到达罗马。
这里:
int array[10] = {1, 2, 3};
int *ptrArrWorking = array; // == &array[0];
您将指针设置为指向数组中的第一项。这意味着指针将获得存储该项目的内存地址。您没有将 地址本身 设置为 1,这在大多数系统上很可能是无意义的。
In the extern case it would be something like
int array[10] = {1, 2, 3};
int *ptrArrNotWorking = array[0];
是的,这是没有任何意义的代码。它实际上甚至不是有效的 C,因为如果不先执行转换就不能将整数分配给指针——这可以通过类型转换来完成。
我知道这个话题已经讨论过几次了,但我还是不明白。
参考http://c-faq.com/aryptr/aryptr2.html
char a[] = "hello";
char *p = "world";
创建数组 "a"。该变量只是第一个内存地址的地址的标签。 p 是一个变量(== 另一个内存地址的标签),包含第一个字符的地址(w - 可能在内存中的其他地方)。
我不明白的是这个主题的例子(谢谢!): using extern to link array with pointer :
extern1.c
extern int *array;
int test();
int main(int argc, char *argv[])
{
printf ("in main: array address = %x\n", array);
test();
return 0;
}
extern2.c
int array[10] = {1, 2, 3};
int test()
{
printf ("in test: array address = %x\n", array);
return 0;
}
为什么extern1中的指针变量"extern int *array"(==内存地址的标号,包含另外一个地址)已经包含数组[0]的内容了?
和
有什么区别int array[10] = {1, 2, 3};
int *ptrArrWorking = array; // == &array[0];
? 在外部情况下,它会像
int array[10] = {1, 2, 3};
int *ptrArrNotWorking = array[0];
编辑:更明确地说,我们将上面的示例解释为
int array[10] = {1, 2, 3};
int *ptrArrNotWorking = (int *)array[0];
所以这模拟了在外部示例中可以看到的相同行为。
间接隐藏在哪里?
非常感谢。
仅使用 extern
declares a variable, but not defines it。
实际上这意味着 array
变量(在 extern1.c 中声明为 extern
)只是实际变量 array
定义在 extern2.c
您在 extern2.c
中定义了一个名为 array
:
int array[10] = {1, 2, 3};
这是包含十个 int
的连续内存段。在将它传递给 test
中的 printf
后,它会衰减为指向其第一个元素的指针——这就是数组传递给函数的方式。因此,printf
打印第一个 int
.
然而,在 extern1.c
中,您在再次声明 array
时撒谎:
extern int *array;
这假装 array
是一个指针,一个保存其他对象地址的对象。这种不匹配导致程序 "ill-formed, no diagnostic required"。那是 "badly broken" 的标准——从那时起,就不再要求程序是否编译,或者它在运行时实际做了什么。
在实践中,该损坏声明之后的代码确实会将 array
视为指针。因此,当您将 array
传递给 printf
时,它会从数组的开头切掉一些字节(通常是 4 或 8,具体取决于您的平台),大喊 "there you go, here's the pointer" 并给出至 printf
.
当然,它实际上不是一个有效的指针,而是array
的前几个int
的比特位塞在一起,所以你看到的是废话。
creates an array "a". The variable is only a label of the address of the first memory address.
不是,a
是整个数组hello[=13=]
。每当在表达式中使用标识符 a
时,数组 "decays" 就会成为指向其第一个元素的指针。也就是说,在使用 a
的表达式中,您将得到一个指向字母 'h'
.
char*
可以这样想:数组就是通往罗马的道路。您询问编译器 "where is the road to Rome, I need to access it",然后它会帮助您设置一个临时路标。这并不意味着通往罗马的道路成为路标。这也不意味着路标本身就是通往罗马的道路。同样,通往罗马的道路不会因为你在上面行驶(访问它)而成为路标。
Why does the pointer variable "extern int *array" (== a label of memory address, containing an other address) in extern1 already contain the content of array[0]?
没有。您不能编写 extern int* array
并期望获得指向分配在别处的数组 int array[10]
中第一项的指针。因为数组不是指针,指针也不是数组。
反汇编示例中发生的事情是代码调用未定义的行为(错误),程序员向编译器撒谎并说 "what's stored here is actually a pointer, trust me" 即使那里没有指针,而是一个整数。
因此,正如在该特定系统上发生的那样,您将指针的地址设置为 1
。不是 pointed-at 数据。这不是你可以依靠的;如果指针和整数在给定系统上具有不同的大小或表示,代码也可能会崩溃。
打个比方,你的编译器就是driver,CPU的程序计数器就是汽车。用 extern int *array
你告诉编译器 "that thing over there a road sign!",指的是实际的道路。编译器然后盲目地按照你告诉它的去做,并尝试从沥青中解释一些方向,然后让汽车跟随它,然后它跑到荒野中,很可能撞毁并且肯定永远不会到达罗马。
这里:
int array[10] = {1, 2, 3};
int *ptrArrWorking = array; // == &array[0];
您将指针设置为指向数组中的第一项。这意味着指针将获得存储该项目的内存地址。您没有将 地址本身 设置为 1,这在大多数系统上很可能是无意义的。
In the extern case it would be something like
int array[10] = {1, 2, 3};
int *ptrArrNotWorking = array[0];
是的,这是没有任何意义的代码。它实际上甚至不是有效的 C,因为如果不先执行转换就不能将整数分配给指针——这可以通过类型转换来完成。