为什么字符串的名称包含c

时间:2018-02-11 04:45:26

标签: c string memory-address

如何可能,字符串的名称包含字符串的地址 - 是的确定 但它的(字符串名称)地址应该不同,但它是相同的

不仅如此,*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] != '\0'){
        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.

我无法理解为什么!

1 个答案:

答案 0 :(得分:2)

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

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

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

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

什么是数组衰减?

因此在大多数情况下,数组将转换为指向第一个元素的指针。这是阵列衰减。请注意这里的情况strchar s的数组 - 当我们在str中使用printf时,它被转换为指向其自身的第一个元素的指针,该地址为str[0]并且指针包含该值。这解释了为什么在打印&str[0]时获得str的值。

阵列衰减有一些例外:

  1. 它是sizeof运算符的操作数。
  2. _Alignof运算符或
  3. 一元&运算符或
  4. 是用于初始化数组的字符串文字。
  5. 有趣的部分是&str,你看到它是操作员&地址的操作数 - 这是一个不会发生衰减的例外。所以&str是一个指向数组对象的指针。类型为char (*)[]。是的,正如你所说,它与str&str[0]具有相同的价值,但它的类型完全不同。

    什么是char(*)[SIZE]

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

    char (*p)[SIZE]char* p[SIZE]相同吗?

    Noo。事实并非如此。第一个是指向char个数组的指针,其中SIZE个元素数量为char* p[]

    char*&str - s的数组。这些都不一样。第一个是表示单个指针,第二个是指针数组。

    另一件事是 - 对于指针,有两件事情重要

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

    第二个指示指针算术将如何取决于它指向的对象类型的大小。在这里,您还看到strprintf(" &str+1 = %p str+1 = %p\n",(void*)(&str+1),(void*)(str+1)); 具有相同的值,但类型不同。如果您看到这些陈述并打印出来,您会感到惊讶。

    &str
      

    提示:第一个char是指向数组的指针。第二个是指向{ versionCode 4 versionName "1.0.1" } 的指针。