1、序

学过c语言的都知道,通常:If(0)之后的代码是不执行的,网上也有详细的说明。

1.1、形式:

if (表达式) { 语句… }

1.2、解释:

在执行if语句时,首先会计算表达式的值,如果表达式的值为零,语句不会执行,若非零,则执行语句。由此可见if (0) 表示不执行,if (1)表示要执行。if (x)根据x的值是否为0来决定是否执行,他等价于if (x != 0)。

if语句中的条件无论是什么最终都要转换成一个布尔值,因此,

1.3、举个例子

if(x)相当于if(x != 0)

对于x为指针,相当于if(x != NULL)

而if(1)

因为1为整型,相当于if(1 != 0)

1肯定不等于0,所以就相当于一定执行if里面的语句.

而if(0)相当于if(0 != 0)

这肯定不成立,所以一定不会执行if中的语句.

x == 1,x != 1也是表达式,称为关系表达式,在C语言里,关系成立,表达式的值为1,不成立则为0,所以1>2的值为0,1!=2的值为1。C语言老师应该提到过,x大于2小于5不能写成 2 < x < 5,因为这货会被解释为(2 < x) < 5,无论x取多少,这个式子的值恒为1(根据刚刚说的应该能理解为什么了吧)。

x=1也是一种表达式,叫赋值表达式,他的值就是等号右边的式子的值,也就是1。所以if(x=1)无论x原来为多少if语句都会成立,并且会将x的值改写为1,和if(x==1)有着非常大的区别(那么,if(x=0)呢?),正是x=1这个表达式是有值的,C语言才允许if(x=1)这种写法,一些语言里x=1这个式子是没有值的,只是将x赋值为1,这样写就会报错,如Java。C语言代码里出现if(x=1)一般情况下是你写错了,可能想表达的是if(x==1)。现在的编译器里,if(x=1)一般都会有警告提示你,可能写错了。

总之,在C语言了里,像if,for,while这些语句本质上都是通过求出括号里表达式的是否为0来决定运行流程的,所以像if(scanf(“%d”,&a))这种代码也是可以理解了的。

上面的文字应该不难理解,过了二级C语言的同学应该都能理解了。

然而。有例外,近期在微信群中看到大佬们提到了Clifford‘s Device,由于一个比较冷门的c语言技巧,趁此学习下。

2、主要参考资料

1、菜鸟教程:C 库函数 – strtol() | 菜鸟教程 (runoob.com)和strtol – C++ Reference (cplusplus.com)以及C++ Shell (cpp.sh)在线运行网站

2、Clifford‘s Homepage – Fun with Program Code。其主页:Claire Wolf (clifford.at),是一个大佬的主页,肯定是比较牛逼的,资料是英文的,不难看懂,看不懂可以谷歌翻译。

这位大佬在文章也提到过Duff‘s Device,这个是比较出名的,他自己想出来一个switch case的代码框架(暂且如此称呼)。经过gcc编译运行,语法没有错。

3、goto版本代码

goto是一个关键字,可以在函数内直接跳转到某个label处再执行,在某些场合是比较适合的,linux中也有用到(linus也是大神~)贴代码之前,上一个库函数的c语言例子先热热身。

C 库函数 – strtol()

包含于标准库 –

——描述

long int strtol(const char *str, char **endptr, int base)

把参数 str 所指向的字符串根据给定的 base 转换为一个长整数(类型为 long int 型),base 必须介于 2 和 36(包含)之间,或者是特殊值 0。

——声明

下面是 strtol() 函数的声明。

long int strtol(const char *str, char **endptr, int base)

——参数

str — 要转换为长整数的字符串。

endptr — 对类型为 char* 的对象的引用,其值由函数设置为 str 中数值后的下一个字符。

base — 基数,必须介于 2 和 36(包含)之间,或者是特殊值 0。

——返回值

该函数返回转换后的长整数,如果没有执行有效的转换,则返回一个零值。

测试代码:

/* strtol example */

#include /* printf */

#include /* strtol */

int main ()

{

char szNumbers[] = "2001 60c0c0 -1101110100110100100000 0x6fffff";

char * pEnd;

long int li1, li2, li3, li4;

li1 = strtol (szNumbers,&pEnd,10);

li2 = strtol (pEnd,&pEnd,16);

li3 = strtol (pEnd,&pEnd,2);

li4 = strtol (pEnd,NULL,0);

printf ("The decimal equivalents are: %ld, %ld, %ld and %ld.n", li1, li2, li3, li4);

return 0;

}

编译运行后:

The decimal equivalents are: 2001, 6340800, -3624224 and 7340031.

接下去,看看大佬的代码

#include

#include

#include

int main (int argc, char** argv)

{

int num;

if (argc != 3)

{

fprintf (stderr, "Usage: %s {BIN|OCT|DEC|HEX|STR} {ARG}n", argv[0]);

return 1;

}

if (!strcmp (argv[1], "BIN") )

{

num = strtol (argv[2], NULL, 2);

goto number_mode;

}

else if (!strcmp (argv[1], "OCT") )

{

num = strtol (argv[2], NULL, 8);

goto number_mode;

}

else if (!strcmp (argv[1], "DEC") )

{

num = strtol (argv[2], NULL, 10);

goto number_mode;

}

else if (!strcmp (argv[1], "HEX") )

{

num = strtol (argv[2], NULL, 16);

goto number_mode;

}

else if (!strcmp (argv[1], "STR") )

{

printf ("Called with string argument: ‘%s‘n", argv[2]);

}

else

{

printf ("Called unsupported mode: ‘%s‘n", argv[1]);

}

/* Clifford‘s Device */

if (0)

{

number_mode:

printf ("Called with numeric argument: %dn", num);

}

return 0;

}

运行后:

编译:

gcc .Clifford-Device-goto.c -o .Clifford-Device-goto.exe

无参数运行,提示报错

.Clifford-Device-goto.exe

Usage: Clifford-Device-goto.exe {BIN|OCT|DEC|HEX|STR} {ARG}

带十六进制参数

.Clifford-Device-goto.exe HEX 0x1234

Called with numeric argument: 4660

0x1234的确=4660

代码测试完成!

这个代码应该不难理解了,具体可以实际上机测试体验下。

4、switch版本代码

这里使用了if(0),直接运行的效果如下:

#include

#define IF_DEF 1

//int main (int argc)

int main (void)

{

char* num;

int argc_test;

for (int i = 0; i < 7; i++)

{

argc_test = i;

#if IF_DEF == 1

printf ("if (0)n");

switch (argc_test - 1)

{

if (0)

{

case 0:

num = "zero";

printf ("==0n");

}

if (0)

{

case 2:

num = "two";

printf ("==2n");

}

if (0)

{

case 3:

num = "three";

printf ("==3n");

}

if (0)

{

case 4:

num = "four";

printf ("==4n");

}

if (0)

{

case 5:

num = "five";

printf ("==5n");

}

if (0)

{

default:

num = "many";

printf ("==...n");

}

printf ("Called with %s arguments.n", num);

break;

case 1:

printf ("Called with one argument.n");

}

#else

printf ("no if (0)n");

switch (argc_test - 1)

{

//if (0)

{

case 0:

num = "zero";

printf ("==0n");

}

//if (0)

{

case 2:

num = "two";

printf ("==2n");

}

//if (0)

{

case 3:

num = "three";

printf ("==3n");

}

//if (0)

{

case 4:

num = "four";

printf ("==4n");

}

//if (0)

{

case 5:

num = "five";

printf ("==5n");

}

//if (0)

{

default:

num = "many";

printf ("==...n");

}

printf ("Called with %s arguments.n", num);

break;

case 1:

printf ("Called with one argument.n");

}

#endif

}

return 0;

}

运行后:

if (0)

==...

Called with many arguments.

if (0)

==0

Called with zero arguments.

if (0)

Called with one argument.

if (0)

==2

Called with two arguments.

if (0)

==3

Called with three arguments.

if (0)

==4

Called with four arguments.

if (0)

==5

Called with five arguments.

部分代码已经做了修改,便于学习。

是不是很疑惑?为何没有break,也没有被fall through,经过咨询大佬,原来switch-case类似于goto-label,难怪其效率是高于if() {} else if()  {} else  {}结构的。另外if(0)可以防止被fall through 对吧,等同于添加了break。

这下应该真相大白了,原来c语言还有这个操作,难以想象,具体的思想可以看原版英文。平时使用还是老老实实的按规范写代码,毕竟项目是需要维护的,而不是秀技巧的。

近期开通了公众号,也一并告知下,

扫描关注:

个人公众号:嵌入式软件自留地

原文链接:https://www.cnblogs.com/CodeWorkerLiMing/p/14726960.html

本文来自网络,不代表手讯网立场。

c语言中if内函数值为零,C语言——if(0)之后的语句真的不会执行吗?相关推荐

  1. 在c语言静态存储类别的,在 C语言中,表示静态存储类别的关键字是 ( ) (1.0分)

    在 C语言中,表示静态存储类别的关键字是 ( ) (1.0分) 在 C语言中,表示静态存储类别的关键字是 ( ) (1.0分) 拜金主义.享乐主义.极端个人主义等错误人生观,其出发点和落脚点都是一己之 ...

  2. c语言中point的用法_关于C语言Switch语句,先学这些技巧够不够?

    一.C语言中switch的用法 1.switch后面括弧内的[表达式],ANSI标准允许它为任何类型: 2.当表达式的值与某一个case后面的常量表达式的值相等时,就执行此case后面的语句,否则,就 ...

  3. c语言中1%3c%3c2 什么意思,c语言练习题

    篇一:C语言考试题库及答案 C语言理论上机考试选择题部分(共200题,仅针对11级定向专业) 1.下面程序的输出是___D______ #include void main() { int k=11; ...

  4. c语言中5l是数值或字符常量,C语言中什么叫做正确的数值或字符常量?

    用一对单引号将一个字符括起表示合法的字符常量.例如'a'.数值包括整型.浮点型.整型可用十进制,八进制,十六进制.八进制前面要加0,后面由0到7八个数表示. 在C语言中,字符常量有以下特点: 字符常量 ...

  5. 在c语言中,字符串topt65的长度是,c语言程序设计期末考试试题(含答案)123612210...

    <c语言程序设计期末考试试题(含答案)123612210>由会员分享,可在线阅读,更多相关<c语言程序设计期末考试试题(含答案)123612210(10页珍藏版)>请在人人文库 ...

  6. c语言中int的取值范围_c语言入门(1)

    c语言入门 C语言一经出现就以其功能丰富.表达能力强.灵活方便.应用面广等特点迅速在全世界普及和推广.C语言不但执行效率高而且可移植性好,可以用来开发应用软件.驱动.操作系统等.C语言也是其它众多高级 ...

  7. c语言中3%3e2%3e1的值,C语言--ch2--数据类型和表达式.ppt

    C语言--ch2--数据类型和表达式 第二章 数据类型和表达式 2.1 数据类型 在C语言中,数据类型可分为:基本数据类型,构造数据类型,指针类型,空类型四大类. 其中基本数据类型可分为: 整型:整数 ...

  8. c语言中eles后面分号的作用,C语言 if else 语句详细讲解

    前面我们看到的代码都是顺序执行的,也就是先执行第一条语句,然后是第二条.第三条--一直到最后一条语句. 但是对于很多情况,顺序结构的代码是远远不够的,比如一个程序限制了只能成年人使用,儿童因为年龄不够 ...

  9. c语言中什么函数可以作为虚函数,C++语言中的“虚函数”就像C语言中的指针,必须要弄懂的...

    上一节较为详细的讨论了C++语言中基类被派生类继承过程中的内存模型,尤其较为详细的分析了虚函数及其虚表.虚表指针在内存中是如何分布,如何存储的,这对于理解C++语言中的"动态绑定" ...

  10. c语言中0x12是什么进制,C语言中进制知识汇总

    1.什么是进制 进制是一种计数的方式,常用的有二进制.八进制.十进制.十六进制.任何数据在计算机内存中都是以二进制的形式存放的. 我对进制的个人理解,二进制数是以2为计算单元,满2进1位的数:八进制数 ...

最新文章

  1. statsmodels 笔记:VAR
  2. 1.1 函数间隔和几何间隔理解1
  3. 使用 Tye 辅助开发 k8s 应用竟如此简单(六)
  4. 二维凸包 Graham's Scan
  5. Windows操作系统的缘由
  6. VTM3.0代码阅读:xCheckRDCostMerge2Nx2N函数
  7. java冒泡排序代码简单_Java冒泡排序简单实现
  8. 华为云notebook在线解压压缩包问题
  9. Kingdee 云星空 7.7 自定义BOM成本查询 替代料用量取0 金额取0
  10. 手机如何测量长度?为什么现在很少携带尺子了
  11. R语言实现关联规则与推荐算法(学习笔记)
  12. MySQL—关联查询与子查询(从小白到大牛)
  13. google map 地理编码API的两种方式
  14. 【Auto.js】给手机编一个模拟遥控器
  15. 【基础语法篇】Java必备基础(思维导图+代码)
  16. WSM ,BSM,SCI,DSRC
  17. MATLAB在线文档打不开,怎么解决
  18. mac使用迅雷下载资源
  19. Windows64位环境下注册32位达梦odbc驱动
  20. 锐起无盘基础学习(一)

热门文章

  1. HTML5 Canvas雨滴下落动画 超逼真
  2. HBase MapReduce实例分析
  3. Oracle中报ora-01033
  4. 一个oracle并发性问题的分析和解决
  5. NspAction与JsonAction区别与用法
  6. GetLogicalDrives,GetLogicalDriveStrings,GetDri...
  7. Dreamweaver自动生成的垃圾代码
  8. golang中base64编码_Golang实现的Base64加密
  9. python程序内存分析_Python中使用MELIAE分析程序内存占用实例
  10. C#解析HL7协议数据2.X