鱼C论坛

 找回密码
 立即注册
查看: 1297|回复: 6

[已解决]Segmentation fault求哥哥姐姐指点

[复制链接]
发表于 2019-2-24 00:01:04 | 显示全部楼层 |阅读模式
5鱼币
本帖最后由 带上面具的孩纸 于 2019-2-24 00:24 编辑
  1. #include"stdio.h"

  2. int main()
  3. {
  4.         char *p1[5] = {"FishC","Five","Star","Good","WoW"};
  5.         char *(*p2)[5] = &p1;
  6.         int i,j;

  7.         for(i = 0;i < 5;i++)
  8.         {
  9.                 for(j = 0;*(*p2)[j] != '\0';j++)
  10.                         {
  11.                                 printf("%c ",*(*p2)[j]);       
  12.                         }
  13.                 printf("\n");
  14.         }
  15. }
复制代码
最佳答案
2019-2-24 00:01:05
本帖最后由 行客 于 2019-2-24 15:05 编辑

你的代码的本意,是想通过数组指针p2,输出指针数组p1里的每个指针如p1[0]指向的字符串里的每个char元素(遇到'\n'结束)。

在开始之前,我们首先来理解三个问题:
1、比如,我们来定义一个char *p="FishC.com";
  1. #include <stdio.h>

  2. int main()
  3. {
  4.         char *p="FishC.com";
  5.         int j=0;

  6.                 for(j = 0; *(p + j) != '\0'; j++)
  7.                 {
  8.                         printf("%c ", *(p + j));
  9.                 }
  10.                 printf("\n");

  11. }
复制代码

输出结果为:F i s h C . c o m
"FishC.com"里的双引号,在编译器编译时完成了3项工作:①给字符串FishC.com后面附加'\0'字符用于表示字符串的结束;②在常量区申请一块连续内存并存放FishC.com及后面的'\0';③将申请到的内存的首地址赋值给指针p。
p指针的类型为char *,也就是p指向的是一个char元素。所以为了输出整个字符串,需要循环输出,并在循环遇到'\0'时停止输出。
另外,需要注意,p+1每次向后移动一个char类型,也就是移动1个字节。

2、对于定义的char *p1[5] = {"FishC","Five","Star","Good","WoW"};这个数组,
p1是一个指针数组。所谓指针数组,就是数组里的每一个元素都是指针。
也就是,char *p1[5]这个数组,所包含的p1[0]、p1[1]、p1[2]、p1[3]、p1[4]的这5个元素,每一个都是char *的指针类型的指针。
比如具体的一个元素,如p1[3],指向的是一个char类型的
作为char *类型的指针,指向的是1个char元素。注意,这里说的是1个。
而这每一个char *元素都指向了一个常量区的字符串的首地址,也就是第一个字符元素。如p1[0]指向了"FishC"的'F',p3[1]指向了"Good"的'G'。

3、char *(*p2)[5] = &p1;
这里的p2是一个数组指针,p2的类型是char *(*)[5]。也就是p2指向p1,所以(*p2)相当于p1。

好,如果你看懂了上面的,那么我们接下来看你的代码:
我们可以将你的代码,改成以下三种形式,实现正常的输出:
第一种方式,直接采用p1数组
  1. #include <stdio.h>

  2. int main()
  3. {
  4.         char *p1[5] = {"FishC", "Five", "Star", "Good", "WoW"};
  5.         char *(*p2)[5] = &p1;
  6.         int i, j;

  7.         for(i = 0; i < 5; i++)
  8.         {
  9.                 for(j = 0; *(p1[i] + j) != '\0'; j++)
  10.                 {
  11.                         printf("%c ", *(p1[i] + j));
  12.                 }
  13.                 printf("\n");
  14.         }
  15. }
复制代码

第二种方式,采用p2指针变相输出
  1. #include <stdio.h>

  2. int main()
  3. {
  4.         char *p1[5] = {"FishC", "Five", "Star", "Good", "WoW"};
  5.         char *(*p2)[5] = &p1;
  6.         int i, j;

  7.         for(i = 0; i < 5; i++)
  8.         {
  9.                 for(j = 0; *((*p2)[i] + j) != '\0'; j++)
  10.                 {
  11.                         printf("%c ", *((*p2)[i] + j));
  12.                 }
  13.                 printf("\n");
  14.         }
  15. }
复制代码

第三种方式,采用数组变形形式输出
  1. #include"stdio.h"

  2. int main()
  3. {
  4.         char *p1[5] = {"FishC","Five","Star","Good","WoW"};
  5.         char *(*p2)[5] = &p1;
  6.         int i,j;
  7.         
  8.         for(i = 0;i < 5;i++)
  9.         {
  10.                 for(j = 0;(*p2)[i][j] != '\0';j++)
  11.                 {
  12.                         printf("%c ",(*p2)[i][j]);        
  13.                 }
  14.                 printf("\n");
  15.         }
  16. }
复制代码


如果理解了上面的三种表达方式,相信你就会完全明白了。
20190223.png

最佳答案

查看完整内容

你的代码的本意,是想通过数组指针p2,输出指针数组p1里的每个指针如p1[0]指向的字符串里的每个char元素(遇到'\n'结束)。 在开始之前,我们首先来理解三个问题: 1、比如,我们来定义一个char *p="FishC.com"; 输出结果为:F i s h C . c o m "FishC.com"里的双引号,在编译器编译时完成了3项工作:①给字符串FishC.com后面附加'\0'字符用于表示字符串的结束;②在常量区申请一块连续内存并存放FishC.com及后面的'\0'; ...
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-2-24 00:01:05 | 显示全部楼层    本楼为最佳答案   
本帖最后由 行客 于 2019-2-24 15:05 编辑

你的代码的本意,是想通过数组指针p2,输出指针数组p1里的每个指针如p1[0]指向的字符串里的每个char元素(遇到'\n'结束)。

在开始之前,我们首先来理解三个问题:
1、比如,我们来定义一个char *p="FishC.com";
  1. #include <stdio.h>

  2. int main()
  3. {
  4.         char *p="FishC.com";
  5.         int j=0;

  6.                 for(j = 0; *(p + j) != '\0'; j++)
  7.                 {
  8.                         printf("%c ", *(p + j));
  9.                 }
  10.                 printf("\n");

  11. }
复制代码

输出结果为:F i s h C . c o m
"FishC.com"里的双引号,在编译器编译时完成了3项工作:①给字符串FishC.com后面附加'\0'字符用于表示字符串的结束;②在常量区申请一块连续内存并存放FishC.com及后面的'\0';③将申请到的内存的首地址赋值给指针p。
p指针的类型为char *,也就是p指向的是一个char元素。所以为了输出整个字符串,需要循环输出,并在循环遇到'\0'时停止输出。
另外,需要注意,p+1每次向后移动一个char类型,也就是移动1个字节。

2、对于定义的char *p1[5] = {"FishC","Five","Star","Good","WoW"};这个数组,
p1是一个指针数组。所谓指针数组,就是数组里的每一个元素都是指针。
也就是,char *p1[5]这个数组,所包含的p1[0]、p1[1]、p1[2]、p1[3]、p1[4]的这5个元素,每一个都是char *的指针类型的指针。
比如具体的一个元素,如p1[3],指向的是一个char类型的
作为char *类型的指针,指向的是1个char元素。注意,这里说的是1个。
而这每一个char *元素都指向了一个常量区的字符串的首地址,也就是第一个字符元素。如p1[0]指向了"FishC"的'F',p3[1]指向了"Good"的'G'。

3、char *(*p2)[5] = &p1;
这里的p2是一个数组指针,p2的类型是char *(*)[5]。也就是p2指向p1,所以(*p2)相当于p1。

好,如果你看懂了上面的,那么我们接下来看你的代码:
我们可以将你的代码,改成以下三种形式,实现正常的输出:
第一种方式,直接采用p1数组
  1. #include <stdio.h>

  2. int main()
  3. {
  4.         char *p1[5] = {"FishC", "Five", "Star", "Good", "WoW"};
  5.         char *(*p2)[5] = &p1;
  6.         int i, j;

  7.         for(i = 0; i < 5; i++)
  8.         {
  9.                 for(j = 0; *(p1[i] + j) != '\0'; j++)
  10.                 {
  11.                         printf("%c ", *(p1[i] + j));
  12.                 }
  13.                 printf("\n");
  14.         }
  15. }
复制代码

第二种方式,采用p2指针变相输出
  1. #include <stdio.h>

  2. int main()
  3. {
  4.         char *p1[5] = {"FishC", "Five", "Star", "Good", "WoW"};
  5.         char *(*p2)[5] = &p1;
  6.         int i, j;

  7.         for(i = 0; i < 5; i++)
  8.         {
  9.                 for(j = 0; *((*p2)[i] + j) != '\0'; j++)
  10.                 {
  11.                         printf("%c ", *((*p2)[i] + j));
  12.                 }
  13.                 printf("\n");
  14.         }
  15. }
复制代码

第三种方式,采用数组变形形式输出
  1. #include"stdio.h"

  2. int main()
  3. {
  4.         char *p1[5] = {"FishC","Five","Star","Good","WoW"};
  5.         char *(*p2)[5] = &p1;
  6.         int i,j;
  7.         
  8.         for(i = 0;i < 5;i++)
  9.         {
  10.                 for(j = 0;(*p2)[i][j] != '\0';j++)
  11.                 {
  12.                         printf("%c ",(*p2)[i][j]);        
  13.                 }
  14.                 printf("\n");
  15.         }
  16. }
复制代码


如果理解了上面的三种表达方式,相信你就会完全明白了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-2-24 01:39:44 | 显示全部楼层
本帖最后由 人造人 于 2019-2-24 01:43 编辑

这个代码好熟悉,之前应该在哪里见过
这个程序是做什么的?
应该不是下面这样

  1. #include <stdio.h>

  2. int main()
  3. {
  4.         char *p1[5] = {"FishC", "Five", "Star", "Good", "WoW"};
  5.         char *(*p2)[5] = &p1;
  6.         int i, j;

  7.         for(i = 0; i < 5; i++)
  8.         {
  9.                 for(j = 0; *((*p2)[i] + j) != '\0'; j++)
  10.                 {
  11.                         printf("%c ", *((*p2)[i] + j));
  12.                 }
  13.                 printf("\n");
  14.         }
  15. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-2-24 16:24:33 | 显示全部楼层
问题出在这2句:
  1.                 for(j = 0;*(*p2)[j] != '\0';j++)
  2.                         {
  3.                                 printf("%c ",*(*p2)[j]);        
  4.                         }
复制代码

应该修改成这样:
  1.                 for(j = 0 ; (* p2)[i][j] != '\0' ; j ++)
  2.                         {
  3.                                 printf("%c " , (* p2)[i][j]) ;        
  4.                         }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2019-2-24 20:38:50 | 显示全部楼层
人造人 发表于 2019-2-24 01:39
这个代码好熟悉,之前应该在哪里见过
这个程序是做什么的?
应该不是下面这样

嘿嘿 是课后作业
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2019-2-24 20:40:23 | 显示全部楼层
行客 发表于 2019-2-24 00:01
你的代码的本意,是想通过数组指针p2,输出指针数组p1里的每个指针如p1[0]指向的字符串里的每个char元素( ...

辛苦了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2019-2-24 20:41:00 | 显示全部楼层
jackz007 发表于 2019-2-24 16:24
问题出在这2句:

应该修改成这样:

谢谢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-3-28 18:56

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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