我知道在C中这两件作品都是:
char* string = "foo";
printf("string value: %s", string);
更简单:
printf("string value: %s", "foo");
但我问自己为什么。
我知道%s
标识符要求参数为char *,string
实际上是(并且它与字符数组相同,因为这两种数据类型是相同的在C)
但是当我直接将字符串传递给printf时,它应该不同吗?我的意思是"foo"
不再是指针......对吗?
答案 0 :(得分:6)
字符串常量"foo"
的类型为char []
。当传递给函数时,数组衰减为指针,即char *
。所以你可以把它传递给一个期望相同的函数。
出于同样的原因,您还可以传递此类型的变量:
char string[4] = "foo";
printf("string value: %s", string);
答案 1 :(得分:2)
"foo"
是字符串文字。它表示一个未命名的数组对象,其静态存储持续时间类型为char[4]
(即没有 const
限定符),它按值传递给函数,就像它一样任何“正常”阵列。
即使数组不是const
,也不允许修改其值。这种修改会导致未定义的行为:
char* string = "foo";
string[0] = 'b'; // wrong, this invokes UB
该数组有四个元素,因为尾随空字符 '\0'
,有时称为NUL
字符。请不要将其与NULL
混淆,这是另一回事。该字符的目的是终止给定的字符串文字。
函数的参数接收指向char
的指针,因为数组对象转换指向数组第一个元素的指针(即指向数组中第一个字符的指针)。确切地说,不是传递整个指针,只传递它所持有的地址(即指针的值)。
答案 2 :(得分:1)
在C中,所有字符串都以null结尾char [],因此您的示例将以相同的方式进行交互。
ISO C标准第7.1.1节以这种方式定义字符串:
字符串是以和结尾的连续字符序列 包括第一个空字符。
答案 3 :(得分:0)
printf()
得到什么,是指针:
ISO / IEC 9899:TC3,6.5.2.2 - 4:
参数可以是任何对象类型的表达式。在准备对函数的调用时,将对参数进行求值,并为每个参数分配相应参数的值.81)
81)声明具有数组或函数类型的参数被调整为具有6.9.1中描述的指针类型。
ISO / IEC 9899:TC3,6.9.1-10:
在进入函数时,将评估每个可变修改参数的大小表达式,并将每个参数表达式的值转换为相应参数的类型,就像通过赋值一样。 (数组表达式和函数指示符作为参数在调用之前转换为指针。)
答案 4 :(得分:-1)
"foo"
是一个指针文字,指向静态分配的4字节内存区域(可能标记为只读),用内容初始化:'f'。 'o','o','\ 0'。