鱼C论坛

 找回密码
 立即注册
查看: 2360|回复: 14

编绎正常,运行异常,请大伙帮忙分析下

[复制链接]
发表于 2014-3-1 20:17:59 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
代码如下:
# include <stdio.h>
int main(void)
{
char a[3][6] = {"Hello", "happy", "good"};  // 声明二维字符数组并初始化
char ** b = a;    // 声明二级字符指针b并用数组名a对其初始化

printf("b[0] = %s\n", b[0]);  // 通过b[0]输出“Hello”

return 0;
}

程序编绎无错,但执行时发生异常,b是二级指针,b[0]应该是指向"Hello"的一级指针,以%s格式输出时应该能输出“Hello”,(类似于printf("a[0] = %s\n", a[0]); 输出Hello),但运行时终止,请大伙帮忙分析下原因
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-3-1 20:31:50 | 显示全部楼层

回帖奖励 +10 鱼币

←_← char ** b = a; 这个会没警告??
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-3-1 20:36:39 | 显示全部楼层
# include <stdio.h>
int main(void)
{
        char a[3][6] = {"Hello", "happy", "good"};  // 声明二维字符数组并初始化
        //char ** b = a;    // 声明二级字符指针b并用数组名a对其初始化
        char * b = a[0];
        int i;
        //printf("b[0] = %s\n", b[0]);  // 通过b[0]输出“Hello”
        //字符串是以0结尾的这是个数组你怎么可以用%s输出呢??
        for(i = 0;i < 6;i++)
        {
                printf("%c",*(b+i));
        }
        return 0;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-3-1 20:37:59 | 显示全部楼层
# include <stdio.h>
int main(void)
{
        char a[3][6] = {"Hello", "happy", "good"};  // 声明二维字符数组并初始化
        char ** b = a;    // 声明二级字符指针b并用数组名a对其初始化
        
        //printf("b[0] = %s\n", b[0]);  // 通过b[0]输出“Hello”
        printf("b[0] = %s\n", b);  // 通过b[0]输出“Hello”
        
        return 0;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-3-1 20:51:24 | 显示全部楼层
楼主,你应该定义b为char (*b)[6]
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-3-1 21:29:54 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-3-1 21:31:10 | 显示全部楼层
牡丹花下死做鬼 发表于 2014-3-1 20:31
←_← char ** b = a; 这个会没警告??

没有警告,如果你觉得不合适,可以这样声明 char ** b = (char **)a; 将a强制类型转换为char **
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-3-2 08:34:34 | 显示全部楼层
a里面没有结束符,用%s 目测会输出 HelloHappyGood还有后面的一长串。:big:big
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-3-2 11:10:05 | 显示全部楼层
a0y1a 发表于 2014-3-1 21:29
你这样可以正常输出,但为什么用b[0]不能正常输出而用a[0]可以呢?

我知道你的意思,要解释清楚这个问题需要画画图,但是我手边没有工具,因此只能再举一个正确的代码给你看:
即把:char** b = a;
改为 char (*b)[6] = a;
本质原因在于a的类型是数组char[3][6]
数组类型会退化为指针类型char(*)[6]
而不会退化为char**
当然如果你十分清楚其间的地址关系尽可以进行随心所欲的操作,但你程序的问题在于*b是一个char*类型但这个类型的值却是由字符'Hell'的ASCII码组成的,因此打印这个值表示的地址得不到有效的字符串。
最后上面的解释可能很难看懂,最好是配有相应的图形解释,但我实在没空,LZ自己慢慢体会。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-3-2 14:22:32 | 显示全部楼层
仰望天上的光 发表于 2014-3-2 11:10
我知道你的意思,要解释清楚这个问题需要画画图,但是我手边没有工具,因此只能再举一个正确的代码给你看 ...

照你所说的,我又改了下输出格式, 把 %s 改成了 %#x ,即 printf("b[0] = %#x\n", b[0]); 输出如下:b[0] = 0x6c6c6568,也就是hell的ASCII码值,是不是原来 hell 在内存中的值被我当作了 char *,也就是字符变量的地址,而我又试图以 %s 格式的形式打印它,因此导致程序无法正常运行?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-3-2 18:40:54 | 显示全部楼层
本帖最后由 小名明SIU 于 2014-3-2 18:42 编辑

要想彻底弄懂,请看C专家编程    下面我简单的说一下,C语言中数组的下标运算都要转成指针运算    你赋值的时候b是二维数组a的首地址。那么你输出的时候是b[0]相当于*b,取出b的地址所指向的元素的值,把他作为%s的字符串的首地址,根据你的程序那个地址是'H'(72),所以以72的首地址输出字符串,很明显那不是你定义的内存(悲剧就此发生)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-3-2 21:11:15 | 显示全部楼层
小名明SIU 发表于 2014-3-2 18:40
要想彻底弄懂,请看C专家编程    下面我简单的说一下,C语言中数组的下标运算都要转成指针运算    你赋值的 ...

谢谢解答,希望有机会能拜读C专家编程,我再慢慢理会
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-3-2 21:42:52 | 显示全部楼层
a0y1a 发表于 2014-3-2 14:22
照你所说的,我又改了下输出格式, 把 %s 改成了 %#x ,即 printf("b[0] = %#x\n", b[0]); 输出如下:b[0 ...

是的。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-3-3 07:20:09 | 显示全部楼层
仰望天上的光 发表于 2014-3-2 21:42
是的。

Thank you!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-3-3 08:41:43 | 显示全部楼层
baidu,google一下再发问题吧
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-23 19:18

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表