| 网站首页 | 业界新闻 | 小组 | 交易 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
买学问 - 大牛一对一辅导,有问必答买学问 - 专业的付费知识问答平台
共有 757 人关注过本帖
标题:结构体中指针与数组,printf无法输出,请大佬帮帮
只看楼主 加入收藏
加冕
Rank: 2
等 级:论坛游民
帖 子:31
专家分:15
注 册:2018-11-24
结帖率:62.5%
  已结贴   问题点数:20  回复次数:10   
结构体中指针与数组,printf无法输出,请大佬帮帮
struct student {
    int a;
    char b[3];
   
};
main()
{    struct student alan={2,"ew"};
     struct student *p=&alan;
     printf("%d%s",p->a,p->b);
     printf("%d%s",*p);
   
 }
不明白为什么第二个printf中 int可以输出,但是char数组无法正常输出,输出的是一个框,框代表地址吗?
用*p不能输出int与char数组吗?
2018-11-24 21:21
Tomorrw_I
Rank: 10Rank: 10Rank: 10
等 级:ID已被封
威 望:6
帖 子:406
专家分:1712
注 册:2018-10-16
  得分:0 
王八的臀部

学C有用吗?
学C++有前途吗?
数据库有必要学吗?
……
别问,你还什么都不会,学就对了
……
2018-11-24 21:29
豆豆的滴
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:湖南
等 级:版主
威 望:30
帖 子:358
专家分:1020
注 册:2018-5-7
  得分:0 
第二个printf根本没输出啊
2018-11-24 21:29
lin5161678
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:15
帖 子:520
专家分:1851
注 册:2011-12-3
  得分:18 
这有点复杂 我能解释 但我估计你看不懂
printf是不定参数函数
第一个参数 会按照char*类型入栈
后面的参数 你怎么写就怎么入栈
然后根据第一个参数的格式控制字符串
从栈里面获取数据 进行输出

第一个printf
入栈了一个int 和 一个char*(数组char[3]隐式转换为指向b[0]的char*)
printf在执行的时候
解析到 %d 从栈里读取一个int 然后输出
解析到 %s 从栈里读取一个char*
然后从这个char*指定的内存地址开始按照char输出数据 直到遇到'\0'
这个char*如前面所说指向b[0] 所以输出数组b的内容
第一个printf的行为就是这样没什么问题

第二个printf
入栈了一个 struct student 展开来说就是 一个int 和 一个char[3] (暂不考虑内存对齐)
printf在执行的时候
解析到 %d 从栈里读取一个int 然后输出
解析到 %s printf会从栈里面读取一个char* 但是入栈的数据并没有char* 而是一个char[3]
这里详细说一下读取一个char*是什么意思
假设char* 是4个字节 读取一个char* 意思是从栈里面读取4个字节的数据 并把读取出来的数据作为一个char*解析
现在栈里面只有char[3] 读取4个字节的数据 会造成数组越界 并且把读取出来的数据作为一个char*解析
就是说b[0]做完char*的第一个字节的数据 b[1]作为char*第二个字节的数据 .......
这样组合出一个char* 然后按照组合出来的char*输出字符串
这显然是胡作非为了


2018-11-24 22:06
lin5161678
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:15
帖 子:520
专家分:1851
注 册:2011-12-3
  得分:0 
强调一下 直接在printf里面写结构体参数属于未定义行为
这个解释仅仅是从某个实现出发对printf的行为进行介绍
并不具备普适性

2018-11-24 22:07
lin5161678
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:15
帖 子:520
专家分:1851
注 册:2011-12-3
  得分:0 
你的第二句printf 相当于
     printf("%d%s",p->a, *(char**)&p->b);

2018-11-24 22:12
lin5161678
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:15
帖 子:520
专家分:1851
注 册:2011-12-3
  得分:0 
如果你企图通过
     printf("%d%s",*p);

输出字符串 可以考虑结构体定义为
程序代码:
struct student {
    int a;
    char* b;
    
};

这样对printf来说 *p展开一样是一个int 一个char*

并且 我再次强调这是一个未定义行为
并不具备普适性
假如int是4字节 char*是8字节 结构体按照8字节对齐
这个操作就残废了
2018-11-24 22:15
Tomorrw_I
Rank: 10Rank: 10Rank: 10
等 级:ID已被封
威 望:6
帖 子:406
专家分:1712
注 册:2018-10-16
  得分:0 
  楼上牛逼!   

学C有用吗?
学C++有前途吗?
数据库有必要学吗?
……
别问,你还什么都不会,学就对了
……
2018-11-24 22:17
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:194
帖 子:6526
专家分:28850
注 册:2014-5-20
  得分:2 
以下是引用加冕在2018-11-24 21:21:24的发言:

struct student {
    int a;
    char b[3];
   
};
main()
{    struct student alan={2,"ew"};
     struct student *p=&alan;
     printf("%d%s",p->a,p->b);
     printf("%d%s",*p);
   
 }
不明白为什么第二个printf中 int可以输出,但是char数组无法正常输出,输出的是一个框,框代表地址吗?
用*p不能输出int与char数组吗?

指针能表达的东西很多,不是个个都一样。
这个 p 表达的是一组数,不是某个数。
2018-11-25 05:17
加冕
Rank: 2
等 级:论坛游民
帖 子:31
专家分:15
注 册:2018-11-24
  得分:0 
回复 4楼 lin5161678
虽然我现在还不太懂,但是谢谢你的回答。

授人以鱼不如授人以渔请说一下用什么方法和需要学习什么来解决问题,谢谢大家
2018-11-25 11:23







关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.030175 second(s), 8 queries.
Copyright©2004-2019, BCCN.NET, All Rights Reserved