C语言字符指针数组中str+i与str[i]的区别及字符串输入打印问题
问题核心错误说明
原代码运行崩溃主要有两个错误:
- 字符指针数组
char *str[5]的每个元素都是未初始化的野指针,没有指向可写入的有效内存空间,输入字符串会触发非法内存访问,属于未定义行为,直接导致程序终止。 scanf("%s", &str[i])参数类型错误:%s要求传入char *类型的内存首地址,而&str[i]是char **类型,类型不匹配。
str+i与str[i]的用法区分 分两种常见场景说明两者的差异:
- 场景1:定义为
char *str[5](指针数组)str是数组首地址,类型为char **str + i是数组第i个元素的地址,等价于&str[i],类型为char **str[i]是数组第i个元素存储的指针值,类型为char *,是scanf("%s")需要的正确参数类型
- 场景2:定义为
char str[5][40](二维字符数组)str是二维数组首地址,类型为char (*)[40]str + i是数组第i行的首地址,等价于&str[i],类型为char (*)[40]str[i]是第i行的数组名,传参时退化为char *类型的指针,指向第i行首元素,与&str[i]的地址数值相同,是scanf("%s")的规范传参方式
可行实现方案
1. 动态内存分配方案
该方案在堆上分配内存,适合字符串长度不确定、需要灵活调整内存大小的场景,注意使用后释放内存避免泄漏:
#include <stdio.h> #include <stdlib.h> int main() { char* str[5]; for (int i = 0; i < 5; i++) { // 为每个指针分配40字节的可用空间 str[i] = (char *)malloc(40 * sizeof(char)); // 传入分配好的内存首地址 scanf("%s", str[i]); } for (int i = 0; i < 5; i++) { printf("%s\n", str[i]); // 释放对应内存 free(str[i]); } return 0; }
2. 二维字符数组方案
该方案在栈上预分配固定大小的连续内存,使用简单无需手动管理内存,适合字符串长度可控的场景:
#include <stdio.h> int main() { // 预分配5行、每行40字节的存储空间 char str[5][40]; for (int i = 0; i < 5; i++) { // 传入第i行的首地址 scanf("%s", str[i]); } for (int i = 0; i < 5; i++) { printf("%s\n", str[i]); } return 0; }
内容的提问来源于stack exchange,提问作者Lucifer The devil
相关产品推荐
相关产品推荐

