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不是指针,因此上述内容可能会在某些平台上崩溃(并在其他平台上导致更糟糕的事情)。