关于char *<variable>[6]与char (*<variable>)[6]的差异及代码问题咨询
嘿,我来帮你把这两个C语言声明的差异掰扯清楚,顺便看看你代码里藏着的小问题~
char *var[6]和char (*var)[6]的核心差异 这俩看起来长得像,其实完全是两种东西:
char *var[6]:指针数组
这是一个包含6个元素的数组,每个元素都是char*类型(指向字符的指针)。它本身是数组类型,如果声明成局部变量,会在栈上分配固定大小的空间(比如64位系统里每个指针占8字节,总共48字节)。你一开始用malloc给它赋值报错,就是因为数组只能用初始化列表(比如char *var[6] = {"123", "456"};)来初始化,不能直接给整个数组赋值指针——它本质不是单个指针类型。char (*var)[6]:指向数组的指针
这本质是一个指针,它指向的是一个包含6个char元素的数组。因为它是指针类型,所以你可以用malloc给它分配堆内存,这也是你改了之后编译通过的原因。这种声明适合管理一批固定长度的字符串,因为它指向的是连续的内存块,每个块都是6个char的数组。
虽然编译过了,但其实有两个关键问题得修正:
内存分配太小了!
你写的malloc(7 * sizeof(char))只分配了7个字节,这远远不够存6个字符串啊!char (*sixString)[6]指向的是一个6字符的数组,如果你要存6个这样的数组,得分配6 * sizeof(char[6])的内存(也就是6*6=36字节,每个数组能存5个有效字符加一个结束符'\0')。之前的7字节会导致输入字符串时缓冲区溢出,这是C语言里非常危险的bug,可能会导致程序崩溃或者其他奇怪的问题。scanf的溢出风险
用%s读取字符串时,如果用户输入的字符数超过了数组的长度(比如超过5个),会直接溢出数组。建议改成scanf("%5s", sixString[i]),这样最多读取5个字符,留一个位置给结束符,避免溢出。
#include <stdio.h> #include <stdlib.h> int main(void){ // 分配6个长度为6的char数组,每个数组可存5个字符+结束符 char (*sixString)[6] = malloc(6 * sizeof(char[6])); // 一定要检查malloc是否成功,避免空指针错误 if (sixString == NULL) { perror("malloc failed"); return 1; } int i; int sum = 0; for(i = 0; i < 6; i++){ printf("Input for the Number %d: ", i + 1); // 限制读取长度,防止溢出 scanf("%5s", sixString[i]); printf("%s\n", sixString[i]); sum += atoi(sixString[i]); } float average = (float)sum / 6 ; printf("Sum is: %d\nAverage is: %.2f\n", sum, average); free(sixString); return 0; }
- 如果你的场景是要存6个长度不一的字符串,那
char *var[6]更合适——你可以给每个指针单独分配不同大小的内存。 - 如果是存6个固定长度的字符串,
char (*var)[6]更方便,因为它是连续的内存块,管理起来更简单。
内容的提问来源于stack exchange,提问作者lowkeyhuman

