请达人们解读一下这个赋值代码

rickys2080 2014-07-15 10:50:23

#include<stdio.h>
int main()
{
int a = ({
1+2;
3+4;
});
printf("%d", a);//输出7, 是3+4的值,求解释:上面a的赋值,是怎么个原理?
}
...全文
366 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
rickys2080 2014-07-23
  • 打赏
  • 举报
回复
引用 11 楼 ForestDB 的回复:
搜下gcc的特殊扩展。
引用 12 楼 Intel0011 的回复:
这里用到一个GNU C的赋值扩展,即使用({...})的形式。这种形式的语句在顺次执行之后,会将最后一次的表达式的赋值作为返回。 int a = ({ int b = 1; int c = 2; b + c; }); // => a is 3
3Q,阁下见多识广,牛
rickys2080 2014-07-23
  • 打赏
  • 举报
回复
引用 17 楼 zgszlhtao 的回复:
这样的代码你都能写出来,果然奇葩
来源详见16楼
zgszlhtao 2014-07-22
  • 打赏
  • 举报
回复
这样的代码你都能写出来,果然奇葩
rickys2080 2014-07-22
  • 打赏
  • 举报
回复
这个问题源自我看linux内核的一段container_of宏的源码:
#define container_of(ptr, type, member) ({             /
         const typeof( ((type *)0)->member ) *__mptr = (ptr);     /
         (type *)( (char *)__mptr - offsetof(type,member) );})
//container_of在Linux Kernel中的应用非常广泛,它用于获得某结构中某成员的入口地址
引用 10 楼 caiwei_cs 的回复:
没什么意义的东西哦。
引用 15 楼 zxh707wk 的回复:
[quote=引用 14 楼 Intel0011 的回复:] [quote=引用 13 楼 zxh707wk 的回复:] [quote=引用 12 楼 Intel0011 的回复:] 这里用到一个GNU C的赋值扩展,即使用({...})的形式。这种形式的语句在顺次执行之后,会将最后一次的表达式的赋值作为返回。 int a = ({ int b = 1; int c = 2; b + c; }); // => a is 3
那不和逗号表达式一样了吗[/quote] 注意赋值扩展中有分号,是语句,且可以声明类型,比逗号表达式强大多了[/quote]功能差不多。。。[/quote]
Intel0011 2014-07-18
  • 打赏
  • 举报
回复
这里用到一个GNU C的赋值扩展,即使用({...})的形式。这种形式的语句在顺次执行之后,会将最后一次的表达式的赋值作为返回。 int a = ({ int b = 1; int c = 2; b + c; }); // => a is 3
707wk 2014-07-18
  • 打赏
  • 举报
回复
引用 14 楼 Intel0011 的回复:
[quote=引用 13 楼 zxh707wk 的回复:] [quote=引用 12 楼 Intel0011 的回复:] 这里用到一个GNU C的赋值扩展,即使用({...})的形式。这种形式的语句在顺次执行之后,会将最后一次的表达式的赋值作为返回。 int a = ({ int b = 1; int c = 2; b + c; }); // => a is 3
那不和逗号表达式一样了吗[/quote] 注意赋值扩展中有分号,是语句,且可以声明类型,比逗号表达式强大多了[/quote]功能差不多。。。
Intel0011 2014-07-18
  • 打赏
  • 举报
回复
引用 13 楼 zxh707wk 的回复:
[quote=引用 12 楼 Intel0011 的回复:] 这里用到一个GNU C的赋值扩展,即使用({...})的形式。这种形式的语句在顺次执行之后,会将最后一次的表达式的赋值作为返回。 int a = ({ int b = 1; int c = 2; b + c; }); // => a is 3
那不和逗号表达式一样了吗[/quote] 注意赋值扩展中有分号,是语句,且可以声明类型,比逗号表达式强大多了
707wk 2014-07-18
  • 打赏
  • 举报
回复
引用 12 楼 Intel0011 的回复:
这里用到一个GNU C的赋值扩展,即使用({...})的形式。这种形式的语句在顺次执行之后,会将最后一次的表达式的赋值作为返回。 int a = ({ int b = 1; int c = 2; b + c; }); // => a is 3
那不和逗号表达式一样了吗
赵4老师 2014-07-15
  • 打赏
  • 举报
回复
引用 7 楼 syrchina 的回复:
赵老师这段话几乎每个分论坛了里都贴了。。。我要好好学习啊。。。
引用 6 楼 zhao4zhong1 的回复:
计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构……
加油。以下常用DOS命令先练练:

C:\>help
有关某个命令的详细信息,请键入 HELP 命令名
ASSOC          显示或修改文件扩展名关联。
ATTRIB         显示或更改文件属性。
BREAK          设置或清除扩展式 CTRL+C 检查。
BOOTCFG        设置 boot.ini 文件的属性以便控制启动加载。
CACLS          显示或修改文件的访问控制列表(ACL)。
CALL           从另一个批处理程序调用这一个。
CD             显示当前目录的名称或将其更改。
CHCP           显示或设置活动代码页数。
CHDIR          显示当前目录的名称或将其更改。
CHKDSK         检查磁盘并显示状态报告。
CHKNTFS        显示或修改启动时间磁盘检查。
CLS            清除屏幕。
CMD            打开另一个 Windows 命令解释程序窗口。
COLOR          设置默认控制台前景和背景颜色。
COMP           比较两个或两套文件的内容。
COMPACT        显示或更改 NTFS 分区上文件的压缩。
CONVERT        将 FAT 卷转换成 NTFS。您不能转换
               当前驱动器。
COPY           将至少一个文件复制到另一个位置。
DATE           显示或设置日期。
DEL            删除至少一个文件。
DIR            显示一个目录中的文件和子目录。
DISKCOMP       比较两个软盘的内容。
DISKCOPY       将一个软盘的内容复制到另一个软盘。
DISKPART       显示或配置磁盘分区属性。
DOSKEY         编辑命令行、调用 Windows 命令并创建宏。
DRIVERQUERY    显示当前设备驱动程序状态和属性。
ECHO           显示消息,或将命令回显打开或关上。
ENDLOCAL       结束批文件中环境更改的本地化。
ERASE          删除一个或多个文件。
EVENTQUERY     显示指定准则的事件日志项目。
EXIT           退出 CMD.EXE 程序(命令解释程序)。
FC             比较两个文件或两个文件集并显示它们之间的不同。
FIND           在一个或多个文件中搜索一个文字字符串。
FINDSTR        在多个文件中搜索字符串。
FOR            为一套文件中的每个文件运行一个指定的命令。
FORMAT         格式化磁盘,以便跟 Windows 使用。
FSUTIL         显示或配置文件系统的属性。
FTYPE          显示或修改用在文件扩展名关联的文件类型。
GOTO           将 Windows 命令解释程序指向批处理程序
               中某个带标签的行。
GPRESULT       显示机器或用户的组策略信息。
GRAFTABL       启用 Windows 在图形模式显示扩展字符集。
HELP           提供 Windows 命令的帮助信息。
IF             在批处理程序中执行有条件的处理过程。
LABEL          创建、更改或删除磁盘的卷标。
MD             创建一个目录。
MKDIR          创建一个目录。
MODE           配置系统设备。
MORE           逐屏显示输出。
MOVE           将一个或多个文件从一个目录移动到另一个目录。
OPENFILES      显示远程用户为了文件共享而打开的文件。
PAGEFILECONFIG 显示或配置页面文件的属性。
PATH           为可执行文件显示或设置搜索路径。
PAUSE          停止批处理文件的处理并显示信息。
POPD           还原由 PUSHD 保存的当前目录上一次的值。
PRINT          打印一个文本文件。
PROMPT         改变 Windows 命令提示。
PUSHD          保存当前目录,然后对其进行更改。
RD             删除目录。
RECOVER        从损坏的磁盘中恢复可读取的信息。
REM            记录批处理文件或 CONFIG.SYS 中的注释。
REN            重新命名文件。
RENAME         重新命名文件。
REPLACE        替换文件。
RMDIR          删除目录。
SET            显示、设置或删除 Windows 环境变量。
SETLOCAL       开始用批文件改变环境的本地化。
SC             显示或配置服务(后台处理)。
SCHTASKS       安排命令和程序在一部计算机上按计划运行。
SHIFT          调整批处理文件中可替换参数的位置。
SHUTDOWN       让机器在本地或远程正确关闭。
SORT           将输入排序。
START          打开单独视窗运行指定程序或命令。
SUBST          将驱动器号与路径关联。
SYSTEMINFO     显示机器的具体的属性和配置。
TASKLIST       显示包括服务的所有当前运行的任务。
TASKKILL       终止正在运行的进程或应用程序。
TIME           显示或设置系统时间。
TITLE          设置 CMD.EXE 会话的窗口标题。
TREE           以图形显示启动器或路径的目录结构。
TYPE           显示文本文件的内容。
VER            显示 Windows 的版本。
VERIFY         告诉 Windows 验证文件是否正确写入磁盘。
VOL            显示磁盘卷标和序列号。
XCOPY          复制文件和目录树。
WMIC           在交互命令外壳里显示 WMI 信息。

有关工具的详细信息,请在联机帮助查看命令行参考。

rickys2080 2014-07-15
  • 打赏
  • 举报
回复
赵老师这段话几乎每个分论坛了里都贴了。。。我要好好学习啊。。。
引用 6 楼 zhao4zhong1 的回复:
计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构……
赵4老师 2014-07-15
  • 打赏
  • 举报
回复
计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构…… 对学习编程者的忠告: 眼过千遍不如手过一遍! 书看千行不如手敲一行! 手敲千行不如单步一行! 单步源代码千行不如单步对应汇编一行! VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。 对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。 (Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。) 不要迷信书、考题、老师、回帖; 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实! 有人说一套做一套,你相信他说的还是相信他做的? 其实严格来说这个世界上古往今来所有人都是说一套做一套,不是吗? 不要写连自己也预测不了结果的代码! 理解讨论之前请先学会如何观察
layershow 2014-07-15
  • 打赏
  • 举报
回复
就是最后一个表达式计算得到的值 1+2;3+4; 最后得到了一个 7 , 只不过赋给一个变量而已 如果 int func() { return 100; } 1+2;3+4;func(); 得到的就是 100 if (3+4) { } if (func()) { } if ({1+2;3+4;}) { }
rickys2080 2014-07-15
  • 打赏
  • 举报
回复
VC的确编译不过,要GCC才行,这是从linux里发现的一种用法,求解释
引用 3 楼 mrlgy 的回复:
vs2010 编译不过
mrlgy 2014-07-15
  • 打赏
  • 举报
回复
vs2010 编译不过
rickys2080 2014-07-15
  • 打赏
  • 举报
回复
gcc编译器。。。
引用 1 楼 Intel0011 的回复:
你用的是什么编译器,竟然可以通过编译
Intel0011 2014-07-15
  • 打赏
  • 举报
回复
你用的是什么编译器,竟然可以通过编译
ForestDB 2014-07-15
  • 打赏
  • 举报
回复
搜下gcc的特殊扩展。
caiwei_cs 2014-07-15
  • 打赏
  • 举报
回复
没什么意义的东西哦。
707wk 2014-07-15
  • 打赏
  • 举报
回复
虽然编译通过,但有警告信息
gcc -Wall -c "001.c" 
001.c: In function ‘main’:
001.c:5:9: warning: statement with no effect [-Wunused-value]
         1+2;
         ^
编译成功结束。

70,014

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧