鱼C论坛

 找回密码
 立即注册
查看: 2719|回复: 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),但运行时终止,请大伙帮忙分析下原因
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

回帖奖励 +10 鱼币

←_← char ** b = a; 这个会没警告??
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-3-1 20:36:39 | 显示全部楼层
  1. # include <stdio.h>
  2. int main(void)
  3. {
  4.         char a[3][6] = {"Hello", "happy", "good"};  // 声明二维字符数组并初始化
  5.         //char ** b = a;    // 声明二级字符指针b并用数组名a对其初始化
  6.         char * b = a[0];
  7.         int i;
  8.         //printf("b[0] = %s\n", b[0]);  // 通过b[0]输出“Hello”
  9.         //字符串是以0结尾的这是个数组你怎么可以用%s输出呢??
  10.         for(i = 0;i < 6;i++)
  11.         {
  12.                 printf("%c",*(b+i));
  13.         }
  14.         return 0;
  15. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-3-1 20:37:59 | 显示全部楼层
  1. # include <stdio.h>
  2. int main(void)
  3. {
  4.         char a[3][6] = {"Hello", "happy", "good"};  // 声明二维字符数组并初始化
  5.         char ** b = a;    // 声明二级字符指针b并用数组名a对其初始化
  6.        
  7.         //printf("b[0] = %s\n", b[0]);  // 通过b[0]输出“Hello”
  8.         printf("b[0] = %s\n", b);  // 通过b[0]输出“Hello”
  9.        
  10.         return 0;
  11. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-3-1 20:51:24 | 显示全部楼层
楼主,你应该定义b为char (*b)[6]
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-3-1 21:29:54 | 显示全部楼层
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

没有警告,如果你觉得不合适,可以这样声明 char ** b = (char **)a; 将a强制类型转换为char **
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-3-2 08:34:34 | 显示全部楼层
a里面没有结束符,用%s 目测会输出 HelloHappyGood还有后面的一长串。:big:big
小甲鱼最新课程 -> https://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自己慢慢体会。
小甲鱼最新课程 -> https://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 格式的形式打印它,因此导致程序无法正常运行?
小甲鱼最新课程 -> https://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的首地址输出字符串,很明显那不是你定义的内存(悲剧就此发生)
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

谢谢解答,希望有机会能拜读C专家编程,我再慢慢理会
小甲鱼最新课程 -> https://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 ...

是的。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

Thank you!
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-3-3 08:41:43 | 显示全部楼层
baidu,google一下再发问题吧
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-5-13 06:53

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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