[英]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.