C语言指针疑问:为何解引用指针无法正确打印字符串?
嘿,别着急,这是C语言里数组和指针容易混淆的经典问题,我来给你拆解清楚~
核心问题:指针类型不匹配
你的代码里有个关键的类型错误:
char * pName = &name;
这里name是char[8]类型的数组("Cameron"有7个字符,加上字符串终止符\0共8个),&name得到的是指向整个数组的指针,它的类型是char (*)[8],而不是char*。虽然这个指针的数值和数组第一个元素的地址是一样的,但它们的类型完全不同,直接赋值会导致后续操作出现问题。
为什么*pName不能正确打印字符串?
当你把&name赋值给char* pName后,pName的类型是char*,解引用*pName得到的是一个char类型的值——也就是数组第一个元素'C'(ASCII码是67)。而printf的%s格式符需要的是一个指向字符串起始位置的指针,你给它传一个char值,它会把这个值当作内存地址去访问(比如尝试访问地址0x43的内存),这属于未定义行为,自然无法正确打印出字符串。
正确的写法
你有两种方式可以修正这个问题:
方式1:直接用数组名赋值给字符指针
数组名在大多数场景下会自动隐式转换为指向第一个元素的指针,所以直接这样写就对了:
char * pName = name;
这时候pName是char*类型,指向字符串的第一个字符'C',直接用printf("%s", pName);就能打印整个字符串(%s会从指针指向的位置开始,一直读到\0为止)。
方式2:使用指向数组的指针(进阶)
如果你确实想使用指向整个数组的指针,需要先正确定义指针类型:
char (*pName)[8] = &name; // 这里的[8]要和数组的长度一致
这时候*pName会得到整个数组,而数组名又会转换为指向第一个元素的指针,所以printf("%s", *pName);就能正常打印出"Cameron"了。
修正后的完整代码
这里给你第一种方式的修正代码,更符合日常使用习惯:
#include <stdio.h> #include <stdlib.h> int main() { char name[] = "Cameron"; char * pName = name; // 修正这里的赋值 printf("Printing string of characters: %s\n", name); printf("Using pointer to print string: %s\n", pName); // 不需要解引用,直接传指针 printf("Printing address of array: %p\n", &name); printf("Printing address of first element: %p\n", pName); return 0; }
运行这个代码,你会发现两个printf都能正确打印出"Cameron",而且&name和pName的数值是一样的(因为数组的地址和第一个元素的地址在内存中是同一个位置),只是类型不同而已。
内容的提问来源于stack exchange,提问作者cameron

