我开始在C语言中学习指针。直到我遇到“使用指针存储字符数组”主题之前,我都很好理解。 突出我的疑问的示例程序如下
#include <stdio.h>
main()
{
char *string;
string = "good";
printf ("%s", string);
}
这将打印字符串,即好。
应该使用指针存储内存地址,换句话说,我们将变量的地址(使用地址运算符)分配给指针变量。 我不明白的是我们如何直接将字符串分配给指针?那也没有地址运算符吗? 另外,我们如何不使用间接运算符(*)来打印字符串?
答案 0 :(得分:3)
像"good"
这样的文字字符串实际上存储为字符的(只读)数组。另外,C语言中的所有字符串都必须终止,并带有特殊的“空”字符'\0'
。
进行评估时
string = "good";
真正发生的是,您使string
指向该数组中的第一个字符。
处理字符串的函数知道如何处理此类指针,并且知道如何使用指针遍历此类数组以查找字符串中的所有字符,直到找到终止符为止。
稍有不同,编译会创建其数组
char internal_array[] = { 'g', 'o', 'o', 'd', '\0' };
然后使string
指向数组中的第一个元素
string = &internal_array[0];
请注意,&internal_array[0]
实际上等于internal_array
,因为数组自然会衰减到指向其第一个元素的指针。
答案 1 :(得分:1)
"cccccc"
是一个字符串文字,它实际上是存储在ReadOnly内存中的char数组。您将指针分配给此文字的第一个字符的地址。
如果要将字符串文字复制到RAM,则需要:
char string[] = "fgdfdfgdfgf";
请记住,数组初始化(在声明时)是唯一可以使用=
将字符串文字复制到char数组(字符串)的地方。
在任何其他情况下,您都需要使用适当的库函数,例如。
strcpy(string, "asdf");
(string
必须有足够的空间来容纳新字符串)
答案 2 :(得分:0)
您的第一问题:
What I don't understand is how are we able to assign a character string directly to the pointer? That too without address operator?
字符串文字是由双引号括起来的零个或多个多字节字符的序列,例如“好”。
来自C标准#6.4.5 [字符串文字]:
...多字节字符序列随后用于初始化静态存储持续时间的 数组 ,长度足以容纳该序列。对于字符串文字, 数组元素的类型为char ,并使用多字节字符序列的各个字节进行初始化.....
在C中,类型为 类型 的表达式将转换为类型为 指向类型的指针的表达式指向数组对象 [很少有例外] 的初始元素。因此,作为数组的字符串文字会衰减为可以分配给类型char *
的指针。
在声明中:
string = "good";
string
指向存储"good"
的数组中的初始字符。
您的第二问题:
Also, how are we able to print the string without the indirection operator (*) ?
来自 printf() :
s
写一个字符串
参数必须是指向字符数组的初始元素的 指针 ...
因此,格式说明符%s
期望指向变量string
的初始元素的指针-指向"good"
的初始字符的指针。因此,您不需要间接运算符(*)。
答案 3 :(得分:0)
我不了解的是我们如何直接将字符串分配给指针?没有地址运算符也可以吗?
将数组分配给某物后,该数组将转换为指针。
"good"
是字符串文字。它有一个 char 5数组,其中包含一个尾随 null字符。它存在于不应尝试写入的内存中。尝试写是未定义行为(UB)。它可能“起作用”,但可能不起作用。代码可能会死掉,等等。
char *string;
declare string as pointer to char。
string = "good";
导致分配。该操作采用"good"
并将该数组转换为其第一个元素char*
的地址和类型('g'
)。然后将char *
分配给string
。
此外,我们如何在没有间接操作符(*)的情况下打印字符串?
printf()
需要一个char *
-与string
类型匹配。
printf ("%s", string);
作为string
传递printf()
到char *
-不进行转换。 printf ("%s",...
期望看到“ ...参数应为指向字符类型数组的初始元素的指针。”然后“将数组中的字符写到(但不包括)终止空字符。” C11§7.21.6.18。