繁体   English   中英

关于在C中打印字符串数组的困惑

[英]Confusion about Printing string arrays in C

这可能是一个初学者的问题,但这一直使我感到困惑。 我知道在c中,数组本身就是指向数组第一个元素的指针。 因此,请考虑以下示例

char *words[LENGTH];
words[0] = "zero";
words[1] = "one";
words[2] = "two";
printf("%s\n",*words);

最终打印zero 但是,我的理解是, words是指向words数组的第一个元素的指针,这是一个char指针=> words是一个指向char的指针的指针。 因此, *words将是char的指针。 因此,我希望在这里打印一个内存地址,而不是实际的字符串。 我在这里误会什么?

我知道在c中,数组本身就是指向数组第一个元素的指针。

这是不正确的-在大多数情况下,输入“的N元件阵列的表达 T ”将被转换为类型“指针的表达T ”,但阵列对象本身不是指针。 没有为指针作为数组对象的一部分预留存储空间。

字符串文字 "zero"类型为“ char 5元素数组”,而"one""two"类型均为"one" char 4元素数组"two"类型(因为字符串以零值字符结尾,因此需要N + 1个元素以存储N个字符的字符串)。

每个字符串文字都是数组表达式,但是由于这些表达式不是sizeof或一元&运算符的操作数,并且由于它们不用于初始化字符数组,因此每个表达式都将转换为指针表达式,并且每个表达式的值是数组第一个元素的地址。

因此,我希望在这里打印一个内存地址,而不是实际的字符串。 我在这里误会什么?

%s转换说明符告诉printf打印从指定地址开始的字符序列,直到看到字符串终止符-这就是为什么您将输出视为zero而不是地址的原因。 要输出指针值,可以使用%p转换说明符,如下所示:

printf( "%p\n", (void *) *words );

您已经了解了对printf所做的工作-在您编写它时, *words实际上是指向char的指针。 %s格式说明符用于打印字符串,因此假定您传递的任何指针实际上都是一个以'\\0'字符结尾的字符数组-c用于存储字符串的格式。 有了这些信息,printf知道它应该只打印数组中的所有字符,直到找到'\\0'这正是本例所做的。 如果您确实要打印该指针的地址,则正确的格式说明符是(如Stargateur的回答中所述) %p

正如@Stargateur回答的那样,您需要同时使用%p标志并使用(void *)。 请注意,它将向您显示第一个字符串的起始地址(“零”),下一个代码将遍历所有字符串并打印其地址(将3个字符串视为2D(二维)字符串数组,具有不同的字符串长度。

#include <stdio.h>
#define LENGTH 3

int main(void)
{
    char *words[LENGTH];
    words[0] = "zero";
    words[1] = "one";
    words[2] = "two";

    int len = 0;
    while(len<(int)LENGTH)
    {
        printf("%s\n", words[len]);
        printf("%p\n", (void *)words[len]);
        len++;
    }
    printf("\n%p\n", (void *)*words); // prints the first address only (the 'zero' address)

    return 0;
}

您实际上很接近,对,c字符串是一个指针 ,其中包含字符串的第一个字符的地址 C字符串不是字节而是地址。 并且printf标志%s期望这些字节的地址。 因此,您确实给了printf()一个地址,但是您要求给printf()显示c字符串的值。 所以“零”。 唯一的错误是您没有阅读printf()的手册。

如果您想要地址,请尝试:

printf("%p\n", (void *)*words);

char *words[LENGTH]; 定义一个char *数组,即char **。 *words等于words[0] ,它表示“零”。

创建这样的char *数组是不安全的。 例如,下面的代码编译OK,但是其行为是不确定的。

char *words[1];
words[0] = "zero";
words[1] = "one";
words[2] = "two";
printf("%s\n", words[2]);

当在char *words[LENGTH]使用* (而不是在乘法中使用* )时,在其中重要的上下文(如在char *words[LENGTH] word成为指向char的指针数组。

就指针而言, *地址运算符处的Value ,它给出存储在特定地址的Value,而&地址运算符 ,给出变量的地址。

printf("%s\n",*words) // prints value at address to which word points 

printf("%p\n",words) // prints address to which word points

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM