为什么字符串的名称在c中包含其自身的地址

why name of string contain address of itself in c

怎么可能,字符串的名称包含字符串的地址 - 是的,好的 但它的(字符串名称)地址应该不同,但它是相同的

不仅如此,*str 给出第一个字符 - 没关系 但 *str 只是值 (6356737),在此代码中 但它本身等于 6356737 而不是 'f'(它只不过是 str[o])

int main()
{
    char str[] = "fdsgugreui";
    printf("\nstr=%u,&str=%u : *str = %c\n",str,&str,*str);
    int i=0;
    while(str[i] != '[=10=]'){
        printf("\n&str[%d] =%u : str[%d] = %c\n ",i, &str[i], i, str[i]);
        ++i;
    }
    return 0;
}

//结果...

str=6356737,&str=6356737 : *str = f
&str[0] =6356737 : str[0] = f
&str[1] =6356738 : str[1] = d
&str[2] =6356739 : str[2] = s
&str[3] =6356740 : str[3] = g
&str[4] =6356741 : str[4] = u
&str[5] =6356742 : str[5] = g
&str[6] =6356743 : str[6] = r
&str[7] =6356744 : str[7] = e
&str[8] =6356745 : str[8] = u
&str[9] =6356746 : str[9] = i

Process returned 0 (0x0)   execution time : 0.150 s
Press any key to continue.

我不明白为什么!

str 是 char 数组,它衰减为指向 char 数组第一个元素的指针 - 与 &str[0].

相同

请注意,str&str 的值相同,但类型不同。 str 衰减为指针 - 所以它变为 char* 但第二个是 char(*)[11] (请注意,当您将数组名称作为 & 的操作数传递时,它不会衰减为指针)这是一个指向数组对象的指针。

打印地址的正确方法是printf("%p",(void*)str);,这对于其他指针变量也是一样的。

str[0]是数组str0位置的内容。就是这样 - 它与拥有地址无关,它是 char。在你的情况下 str[0] 只不过是 'f'.

什么是数组衰减?

所以在大多数情况下,数组被转换为指向第一个元素的指针。这是数组衰减。注意这里的情况 str 是一个 chars 的数组——当我们在 printf 中使用 str 时,它被转换为指向其自身第一个元素的指针,即地址str[0] 并且指针包含该值。这解释了为什么在打印 str.

时得到 &str[0] 的值

数组衰减有一些例外:

  1. 它是sizeof运算符的操作数。
  2. _Alignof 运算符,或
  3. 一元 & 运算符,或
  4. 是用于初始化数组的字符串文字。

有趣的部分是 &str,在这里您可以看到它是 & 运算符地址的操作数 - 这是不会发生衰减的异常。所以 &str 是一个指向数组对象的指针。类型是 char (*)[]。是的,正如您所说,它将与 str&str[0] 具有相同的值,但它的类型完全不同。

什么是 char(*)[SIZE]

它表示指向大小为 SIZE 的字符数组的指针。数组中有 SIZE 个元素。

char (*p)[SIZE]char* p[SIZE]一样吗?

不。不是。第一个是指向 char 数组的指针,该数组具有 SIZE 个元素。

char* p[]char*-s 的数组。这些是不一样的。第一个表示单个指针,第二个表示指针数组。

另一件事是 - 对于指针来说,有两件事很重要

  • 指针的值。
  • 指针的类型。

第二个指示指针算法将如何取决于它指向的对象类型的大小。在这里您还看到 &strstr 具有相同的值但不是相同的类型。如果您看到这些声明并打印出来,您会感到惊讶。

printf(" &str+1 = %p str+1 = %p\n",(void*)(&str+1),(void*)(str+1));

提示:第一个&str是一个指向数组的指针。第二个是指向 char 的指针。