char a[]="this is an array of characters"; // declaration type 1
char *b="this is an array of characters";// declaration type 2
在这里,您要声明两个变量,a
和b
,并初始化它们。"this is an array of characters"
是一个字符串文字,在 C 中它的类型为 char 数组。a
具有 char 类型数组。在这种特定情况下,数组不会转换为指针,而是a
使用数组进行初始化"this is an array of characters"
。b
具有指向 char 的类型指针,数组被转换为指针,并b
使用指向数组的指针进行初始化"this is an array of characters"
。
printf("%s",*b); // gives a segmentation fault
printf("%s",b); // displays the string
在表达式中,*b
取消引用指针b
,因此它计算为 所指向的字符b
,即:T
。这不是一个地址(这是“%s”所期望的),所以你会得到未定义的行为,很可能是崩溃(但不要尝试在嵌入式系统上这样做,你可能会得到神秘的行为和损坏的数据,这比崩溃更糟糕)。在第二种情况下,%s
需要一个指向 char 的指针,得到它,然后可以继续做它的事情。
char *d=malloc(sizeof(char)); // 1)
scanf("%s",d); // 2)
printf("%s",d);// 3)
在 C 中,sizeof
以字节为单位返回对象的大小(= 存储区域)。在 C 中,一个 char 被定义为与一个字节相同,它至少有 8 位,但可以有更多(但一些标准提出了额外的限制,例如:POSIX 需要 8 位字节,即:八位字节)。因此,您分配了 1 个字节。当你调用 时scanf()
,它会毫无顾忌地写入 指向的内存d
,覆盖所有视线。scanf()
允许最大字段宽度,因此:
- 分配更多内存,至少足以满足您的需求 + 1 终止 ASCII NUL。
- 告诉
scanf()
停止,例如:scanf("%19s")
最多 19 个字符(您需要 20 个字节来存储它,计算终止的 ASCII NUL)。
最后(如果降价让我):
char c=malloc(sizeof(char)); // 4)
scanf("%c",c); // 5)
printf("%c",c);// 6)
c
不是指针,因此您试图将地址存储在不应该的位置。In scanf
,"%c"
需要一个指向 char 的指针,它应该指向一个对象(=存储区域),该对象具有足够的空间用于指定的字段宽度,默认情况下为 1。由于c
不是指针,因此上述内容可能会在某些平台上崩溃(并在其他平台上导致更糟糕的事情)。