搜索
bottom↓
回复: 21

关于C结构体指针初始化语法的疑问?

[复制链接]

出0入0汤圆

发表于 2019-1-17 10:51:38 | 显示全部楼层 |阅读模式
本帖最后由 wq_601840968 于 2019-1-17 10:52 编辑

如下图:


标号处语法不太明白。

本帖子中包含更多资源

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

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入93汤圆

发表于 2019-1-17 10:59:36 | 显示全部楼层
今年2019年了,C99标准到现在已经20年了,有空还是看一下吧。最好C11标准也看下,万一啥时用到了呢。

出0入0汤圆

发表于 2019-1-17 11:04:57 | 显示全部楼层
现在的keil 能在函数中间定义局部变量吗?

出0入0汤圆

 楼主| 发表于 2019-1-17 11:13:20 | 显示全部楼层
takashiki 发表于 2019-1-17 10:59
今年2019年了,C99标准到现在已经20年了,有空还是看一下吧。最好C11标准也看下,万一啥时用到了呢。 ...

匿名结构体?

出0入0汤圆

发表于 2019-1-17 11:15:24 | 显示全部楼层
看这里 常规操作
http://gcc.gnu.org/onlinedocs/gcc-3.4.5/gcc/Designated-Inits.html

出0入93汤圆

发表于 2019-1-17 11:17:52 | 显示全部楼层

1、结构体指定初始化
2、复合字面量
这两项你都看一下,你就明白了。这个不是匿名的,他不是有名字嘛。

出0入93汤圆

发表于 2019-1-17 11:24:08 | 显示全部楼层
RAMILE 发表于 2019-1-17 11:04
现在的keil 能在函数中间定义局部变量吗?

MDK可以。加上gnu或c99编译选项或者干脆上C++。
C51似乎连C89都没有完全遵守,估计是不行的,不过可以用{}括起来,局部变量只要位于{}块语句开头就可以了,switch语句除外。

出0入0汤圆

 楼主| 发表于 2019-1-17 11:38:40 | 显示全部楼层
takashiki 发表于 2019-1-17 11:17
1、结构体指定初始化
2、复合字面量
这两项你都看一下,你就明白了。这个不是匿名的,他不是有名字嘛。 ...

soga,复合字面量

出0入0汤圆

发表于 2019-1-17 13:37:57 | 显示全部楼层
ISO/IEC 9899:2018 都出来了,国内售价¥1388

出0入362汤圆

发表于 2019-1-17 16:17:30 | 显示全部楼层
本帖最后由 tomzbj 于 2019-1-17 16:18 编辑

感觉有点多此一举
如果是初始化结构体, 直接foo_t t={1,2}就可以;
如果在程序中间赋值, 可以t = (foo_t){1,2};
匿名结构体也可以作为函数参数.
以下程序用gcc -Wall编译正常运行, 无warning.

  1. #include <stdio.h>

  2. typedef struct {
  3.     int a;
  4.     float b;
  5. } test_t;

  6. void func(test_t* t)
  7. {
  8.     printf("%d %f\n", t->a, t->b);
  9. }

  10. int main(void)
  11. {
  12.     test_t t1 = {2, 3.0};          // 正常初始化
  13.     func(&t1);

  14.     test_t t2;
  15.     t2 = (test_t) {7, 5.0};      // 需要强制类型转换
  16.     func(&t2);
  17.     func(&(test_t){1, 2.0});      // 匿名结构体作为函数参数
  18.     return 0;
  19. }
复制代码

出0入8汤圆

发表于 2019-1-17 17:09:47 | 显示全部楼层
tomzbj 发表于 2019-1-17 16:17
感觉有点多此一举
如果是初始化结构体, 直接foo_t t={1,2}就可以;
如果在程序中间赋值, 可以t = (foo_t){1, ...

当然不是多此一举。

如果用别人的库,别人改动了结构体成员位置,比如

  1. typedef struct {
  2.     int a;
  3.     float b;
  4. } test_t;
复制代码
改成了

  1. typedef struct {
  2.     float b;
  3.     int a;
  4. } test_t;
复制代码


指定变量去初始化,怎么改都不怕。。。


出0入0汤圆

发表于 2019-1-17 20:02:25 | 显示全部楼层
tomzbj 发表于 2019-1-17 16:17
感觉有点多此一举
如果是初始化结构体, 直接foo_t t={1,2}就可以;
如果在程序中间赋值, 可以t = (foo_t){1, ...

test_t t1 = {2, 3.0};          // 正常初始化

这是书上严厉打击的赋值方法,如果有人修改结构体,出一堆bug

出0入0汤圆

发表于 2019-1-17 20:47:19 | 显示全部楼层
RAMILE 发表于 2019-1-17 20:02
test_t t1 = {2, 3.0};          // 正常初始化

这是书上严厉打击的赋值方法,如果有人修改结构体,出一 ...

一般都是 用“.”  或者“->” 赋值

出200入2554汤圆

发表于 2019-1-17 21:21:08 | 显示全部楼层
这个语法在 VS8.0 (2005)下直接不通过,不知其他版本的 VS 是否也是这个特性。

相应的,VS 一般使用构造函数(结构体也有)来初始化结构体,连初始赋值都少用了。

出200入2554汤圆

发表于 2019-1-17 21:22:18 | 显示全部楼层
tomzbj 发表于 2019-1-17 16:17
感觉有点多此一举
如果是初始化结构体, 直接foo_t t={1,2}就可以;
如果在程序中间赋值, 可以t = (foo_t){1, ...

VS8.0 下 C++ 环境,第 19、21 行直接报错,看来 VS 环境检查的也挺严

出0入0汤圆

发表于 2019-1-17 21:32:33 来自手机 | 显示全部楼层
t3486784401 发表于 2019-1-17 21:22
VS8.0 下 C++ 环境,第 19、21 行直接报错,看来 VS 环境检查的也挺严

这不是严格而是一直vs不支持c99。新的vs好像才支持

出0入93汤圆

发表于 2019-1-17 21:34:40 | 显示全部楼层
t3486784401 发表于 2019-1-17 21:21
这个语法在 VS8.0 (2005)下直接不通过,不知其他版本的 VS 是否也是这个特性。

相应的,VS 一般使用构造 ...

他这个是C,你用C++去编译,报错很正常好吧。
C++和C是两种完全不一样的语言,C++从来就没有100%兼容过C语言,凡是到处鼓吹C++完全兼容C的,都是骗人的:就算是C89,C++也不完全兼容。从C99开始,不兼容进一步扩大;到C11时,基本上就是儿童相见不相识笑问客从何处来了。
C99好多特性都是从GCC演化而来,所以GCC的C++可能会兼容,但是VS的C++可以根本不鸟,本来就不是标准。

出200入2554汤圆

发表于 2019-1-17 23:20:12 | 显示全部楼层
nanfang2000 发表于 2019-1-17 21:32
这不是严格而是一直vs不支持c99。新的vs好像才支持

看了看,的确 VS 对于 C99 的支持一般般

出200入2554汤圆

发表于 2019-1-17 23:21:09 | 显示全部楼层
takashiki 发表于 2019-1-17 21:34
他这个是C,你用C++去编译,报错很正常好吧。
C++和C是两种完全不一样的语言,C++从来就没有100%兼容过C ...

受教了,看样子都是神仙打架

出200入2554汤圆

发表于 2019-1-17 23:42:20 | 显示全部楼层
takashiki 发表于 2019-1-17 21:34
他这个是C,你用C++去编译,报错很正常好吧。
C++和C是两种完全不一样的语言,C++从来就没有100%兼容过C ...

手头单片机的 C 编译器都不行,目前可以通过的只有 Arduino (G++)

不过 G++ 这个只能支持结构体顺序初始化,乱序的初始化也是不支持。

出0入93汤圆

发表于 2019-1-18 05:56:04 | 显示全部楼层
t3486784401 发表于 2019-1-17 23:42
手头单片机的 C 编译器都不行,目前可以通过的只有 Arduino (G++)

不过 G++ 这个只能支持结构体顺序初 ...

底层是GCC或支持GCC扩展的都可以,比如WinAVR、ARM GCC、Keil MDK加上--gnu控制。
支持C99的单片机编译器也不少了,IAR for ARM、Keil MDK,不过默认都是C89的,需要在选项中开启。
支持C11的编译器是真没见过,网上的信息也不多,还有很多挂羊头卖狗肉的,标题写C11,内容写C++11的。

出0入0汤圆

发表于 2019-2-4 18:03:23 | 显示全部楼层
tragedy 发表于 2019-1-17 11:15
看这里 常规操作
http://gcc.gnu.org/onlinedocs/gcc-3.4.5/gcc/Designated-Inits.html

为什么推荐 gcc 3.4.5 版本的文档呢?  最新的是gcc 8了,
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-25 23:44

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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