Array变量是否指向自身?

我尝试了一些代码来检查数组和指针的行为。 其内容如下。

#include  main(){ int s[]={1,2}; int *b=s; printf("%d, %d, %d\n", s, &s, *s); printf("%d, %d, %d\n", b ,&b, *b); } 

最初我认为指针和数组是相同的但是…
令我惊讶的是,’s’和’&s’的价值与’b’不同。 这是否意味着一个数组变量“指向自己?”

我现在也对实际上变量“名称”感到困惑? 如何与内存中的位置进行绑定? 我只是无法想象那里发生的事情! 内存(RAM)中的所有信息都是在运行时存储的?

除非它是sizeof或一元&运算符的操作数,或者是用于初始化声明中的另一个数组的字符串文字,否则“N元素数组T ”的表达式将替换为类型“的表达式”指向T “的指针,表达式的值将是数组中第一个元素的地址。

假设以下代码:

 int arr[10]; foo(arr); 

在对函数foo的调用中,表达式arr从类型“10-element array of int ”转换为“指向int ”,而arr的第一个元素的地址实际上是传递给foo

我们将foo定义为

 void foo(int a[]) {} 

要么

 void foo(int *a) {} 

在函数参数声明的上下文中, T a[]T a[N]T *a相同; 参数是指针类型,而不是数组类型。 请注意,这适用于函数参数声明。

如上所述,此规则的一个例外是当数组表达式是一元&运算符的操作数时。 如果我们将对foo的调用更改为read

 foo(&arr); 

那么表达式&arr的类型是“指向10个元素的int数组”,或者是int (*)[10] ,表达式的值是a的地址。 为此, foo的定义是

 void foo(int (*a)[10]) {} 

在C中, 数组的地址和数组的第一个元素的地址是相同的 – 因此表达式arr&arr都具有相同的 ,但它们的类型是不同的。 这对涉及指针运算的操作很重要。 例如,假设我们的代码已经编写完成

 int arr[10]; foo(arr); ... void foo(int *a) { ... a++; ... } 

进入时,指向arr[0] 。 表达式a++会使指针前进指向数组中的下一个整数( arr[1] )。

现在假设代码已写为

 int arr[10]; foo(&arr); ... void foo(int (*a)[10]) { ... a++; ... } 

在进入时,仍然指向arr[0] (记住,数组的地址与数组的第一个元素的地址相同),但这次表达式a++将使指针前进指向下一个10 -element整数数组 ; 而不是推进指针sizeof (int)字节,我们推进sizeof (int[10])字节。

所以这就是为什么在你的printf语句中你会看到s&s的相同 。 您应该使用%p转换说明符来打印指针值,并且它期望相应的参数为void *类型,因此将这些printf语句更改为

 printf("%p %p %d\n", (void *) s, (void *) &s, *s); printf("%p %p %d\n", (void *) b, (void *) &b, *b); 

好吧,让我们说以下是执行时内存的外观

 int s[]={1,2}; int *b=s; s[] +-----+-----+ | 1 | 2 | +-----+-----+ 100 104 ^ | | int *b = &s +-----+ | 100 | +-----+ 200 

s是一个数组。 这意味着,它是一个与变量s相关联的连续内存位置,并且通过偏移数组变量名来访问每个元素。

因此,当你使用s它实际上归结为数组的地址(在这种情况下为100 )。 当你做*s ,它归结为*(s+0) ,相当于s[0] ,所以*s代表存储在第零位置的内容(在这种情况下, s[0]1 )。 什么时候做&s ,这将打印&s的地址s (which is在这种情况下s (which is 100`)。

注意,这里s&s代表一个地址; *ss[x]表示整数。

这同样适用于指针。 因此, b打印它所拥有的内容,即s的地址(在这种情况下为100 )。 &b打印&b的地址,在这种情况下为200 。 并且, *b打印数组s的第一个元素的内容,即1

我修改了你的程序,让它打印地址。

 #include  int main(void) { int s[]={1,2}; int *b=s; printf("%p, %p, %d\n", (void *)s, (void *)&s, *s); printf("%p, %p, %d\n", (void *)b, (void *)&b, *b); return 0; } 

输出:

 0xbfc4f3e4, 0xbfc4f3e4, 1 0xbfc4f3e4, 0xbfc4f3ec, 1 

编辑: %p期望void * 。 添加相同!

当数组用作函数的参数时,它会衰减为指向其第一个元素的指针。 类似地,获取数组的地址会产生指向第一个元素位置的指针(但具有不同的类型)。

至于你的第二个问题,变量名只存在于编译时。 它通常在运行时没有内存中的表示。

考虑这个的一个简单方法是作为指针的数组不能通过赋值来改变,它实际上是指向已知内存量的常量指针。

要尝试,请使用:

 myptr = myarray; 

哪个完全没问题,然后尝试:

 myarray = myptr; 

哪个不是。