C语言数组、指针与函数应用问题咨询:程序未按预期输出字符
你的C程序遍历字符串字符失败的原因及修正方案
一、核心错误分析
1. 数组声明与初始化不匹配
你声明的char *str[2][15]是2行15列的字符指针数组,但初始化逻辑完全错误:
- 若要存储多个字符串,正确的声明应为
char *str[2](指针数组,每个元素指向字符串字面量的首地址),或char str[2][20](二维字符数组,直接存储字符串内容,需预留\0的空间)。 - 原声明中
str[2][15]的每个元素是char*类型,直接用字符串字面量初始化只会给str[i][0]赋值,其余str[i][1]到str[i][14]都是未初始化的野指针,完全不符合你的需求。
2. 指针类型不匹配导致地址乱指
ptr = &str[0][0];:str[0][0]是char*类型,取地址后为char**类型,赋值给char*类型的ptr会触发类型不匹配,导致指针指向错误内存区域。str1(*ptr, 2);:若ptr是char**类型,*ptr才是char*;但原程序中ptr是char*,*ptr是单个字符,将字符传给需要char*的函数参数,逻辑完全错误。
3. 函数内的遍历逻辑非法
在str1函数中:
- 参数
str1是char*类型,str1[i][j]相当于访问char类型元素后再做二维下标,属于非法内存访问,会触发越界。 printf("%s", *str1[i][j]);:%s要求传入字符串首地址(char*),但此处*str1[i][j]是单个字符,类型不匹配会触发未定义行为(程序崩溃或乱码)。
二、修正后的代码方案
方案1:使用指针数组存储字符串
适合存储长度不一的字符串:
#include <stdio.h> // 接收指针数组的首地址 void str1(char **str, int count); int main() { // 指针数组,每个元素指向字符串字面量 char *str[2] = { "You know what", "C is powerful" }; str1(str, 2); return 0; } void str1(char **str, int count) { // 遍历每个字符串 for (int i = 0; i < count; i++) { // 遍历字符串的每个字符,直到遇到终止符'\0' for (int j = 0; str[i][j] != '\0'; j++) { printf("%c ", str[i][j]); // 用%c打印单个字符 } printf("\n"); // 每个字符串打印完换行 } }
方案2:使用二维字符数组存储字符串
适合存储长度固定的字符串:
#include <stdio.h> // 指向长度为20的字符数组的指针 void str1(char (*str)[20], int count); int main() { // 二维字符数组,预留足够空间存储字符串及终止符 char str[2][20] = { "You know what", "C is powerful" }; str1(str, 2); return 0; } void str1(char (*str)[20], int count) { for (int i = 0; i < count; i++) { for (int j = 0; str[i][j] != '\0'; j++) { printf("%c ", str[i][j]); } printf("\n"); } }
三、关键知识点总结
- 指针数组 vs 二维字符数组:指针数组存储字符串地址,适配长度不一的字符串;二维字符数组是连续内存块,适合长度固定的场景。
- 数组的函数传递规则:一维数组传递时会退化为指针;二维数组传递需指定第二维长度(如
char (*str)[20]),或用char**接收指针数组。 - 字符串遍历逻辑:字符串以
'\0'为终止标志,遍历到该字符即停止,避免用固定长度循环(除非明确字符串长度且包含终止符)。
内容的提问来源于stack exchange,提问作者Ajayi Olajide
相关产品推荐
相关产品推荐

