作者:cggwz

来源:https://blog.csdn.net/cggwz/article/details/103740713?utm_medium=distribute.pc_relevant.none-task-blog-utm_term-2&spm=1001.2101.3001.4242

文章目录

  • 运算符相关

    • 自增(减)前后缀

    • 逻辑运算符的短路问题

    • 赋值运算符的返回值问题

    • 运算符优先级的问题

    • sizeof()的返回值问题

  • 函数相关

    • 函数声明问题

    • mian函数参数问题

  • 变量相关

    • 用字符串初始化字符数组

    • 赋初值问题

    • 转义字符问题

    • 常用ASCII码记忆

    • 字符串常量占用内存问题

    • 字符变量值的问题

    • 变量类型的范围计算问题

    • 字符串常量拼接问题

  • 数组相关

    • 数组下标越界

    • 二维数组中行列计算问题

    • 字符数组赋值问题

  • 结构体相关

    • 结构体所包含的变量不可初始化

    • 查看结构体内部变量所占内存大小

  • 库函数相关

    • 绝对值函数

    • scanf()和printf()的返回值问题

    • fclose()的返回值问题

  • 预编译相关

    • 注意宏定义的替换原则

  • 后记

现在不少大学都把C语言作为一门必学的编程语言。C语言考试呢,并不能决定你的实践能力怎么样,他考的很多点,我们不知道,也可以在写代码时避免,我们举个最简单的例子,运算符优先级,这恐怕是必考的内容了。但实际上我们写代码并不需要背下这个,我们完全可以通过多加几个括号解决问题。但是考试它并不会管这些,考试是别人出的题,所以代码也是它的。而我们也需要一个较高的分数,那么我们应该怎么办呢?
没错,这篇博客就是为了这个而诞生的。从cggwz个人的刷题经历,总结出易错的一些点,提醒大家在考试中注意,那么废话不多说,我们开始吧!
(再强调一遍:这里大部分是出卷人可能的设误点,而不一定是你自己写代码的易错点)

运算符相关

自增(减)前后缀

我们以自增为例,前缀和后缀的差别有两点:

  1. 优先级不同,后缀优先级更高

  2. 返回值不同

虽说优先级不同,但是在两者之间也就逻辑非和按位取反,貌似不会有太大影响。
而重点是返回值,也就是说,++x返回的是x+1,而x++返回的是原来的x。
而x本身的值都会在返回值以后立刻改变,也就是执行这个表达式后立即改变,比如:

#includeint main(){    int x=0,y=2,z=1;   x=z++ + z;    printf("%d",x); return 0;}

这个输出结果就是3,而不是2.

逻辑运算符的短路问题

C语言在计算逻辑运算符的时候是采取短路机制的,也就是说,如果已经可以判断这个表达式的最终结果,那么就不再判断接下来的表达式,相应地,那些表达式也不会被执行。而出题人则喜欢通过放置一些赋值语句在后面,某些学生会因为忽略了短路机制,而误以为会执行,从而出错,我们看个例子:

#includeint main(){  int x=3,y=2,z=1;   y=--z&&--x;  printf("%d",x); return 0;}

这里输出是2吗?
并不是,是3.
因为--z返回的值是0,而后面的逻辑运算符是&&,也就是说无论后面一个语句真假与否,这个表达式都是假,所以就会触发短路机制,不再计算后面的++x,从而x的值不会改变。
我们来看个变式:

#includeint main(){   int x=3,y=2,z=1;   y=--z&&--x||--x; printf("%d",x); return 0;}

相信你现在应该能知道结果了,输出就是2.中间的那个–x并不会因为它在中间而被执行。

赋值运算符的返回值问题

我们知道C语言中的赋值运算符是有返回值的。
它们的返回值是赋值后被赋值变量的值,而不是赋值符号右边的表达式的值
比如int a=10;a+=3;这里的+=返回的就不是3,而是13.
这也适用于类型转换问题,比如double a;a=2;这里这个赋值语句的返回值就是2.0,而不是2.

运算符优先级的问题

考试前必须要掌握的内容之一。
但是显然,我这里不会把一大张表放出来,要是需要看看课本就好了。
这里我是想总结一下这张表,让大家更容易的“记住”这张表。
我们也会顺带地总结一下结合方向。
现在请翻开你的教材或是百度找到一张表,我们准备开车了。
首先第一梯队,优先级最高的,是一些指代所属关系的运算符,比如[]、->、.。在加上一个圆括号。这个应该很好理解。圆括号如同一个老大哥,它在改变运算顺序这方面具有绝对的话语权,自然会在第一梯队,而这个老大哥也是懂人情的,->、.这类符号就好像是调用父对象里的一个子对象,把人家父子关系拆散恐怕不是一个老大哥应该做的,所以它们也属于第一梯队。
它们的优先级是最高的。
接下来第二梯队主要是我们的单目运算符。比如正负号、指针符号、取地址、自加自减之类。它们通常是紧紧贴着它们作用的对象的(单目),那关系亲密地如同情侣。虽然狗粮不好吃,但是不能因为嫉妒就拆散人家呀(谁说的,我就觉得可以),所以它们的优先级也是比较高的,属于第二梯队。
第三梯队就是我们的四大金刚啦——加减乘除,哦不,我们不能忘了我们除法的好兄弟——取余。所以它们五个就是我们的第三梯队,我们可以把它们叫做算术运算符。这五大金刚可是从小学就开始陪伴我们了,自然在考虑完父子情、情侣情之后要考虑它们几个了。
第四梯队是位运算的左移和右移运算符。这两个家伙虽然名气没有上面五大金刚大,但是它们也是可以改变变量的值呢,也可以算得上小金刚了。所以,第四梯队,当之无愧。
第五梯队是关系运算符,也就是表示大于小于不等这类符号。它们虽然也很早就开始陪伴我们,名气也不小,但是毕竟是比较运算的结果,自然要等前两个梯队运算完,才能比较,那就只好屈居它们后面啦。
第六梯队是位运算的按位与、或、异或。理论上它们也是改变数值的呀,为什么不在前面的梯队呢?我们可以看看它们的样子:&、|,正好是我们下面一个梯队的一半,二者的关系情同手足,成功固然美好,但是一份兄弟情,哪是成功可以换来的?它们自然愿意留在兄弟身旁,相依相助。
第七梯队是逻辑运算符,加上唯一一个三目运算符——条件运算符。它们连接的多半是关系运算符的结果,自然就得在关系运算符后面啦!
第八梯队可是一个大部队,赋值运算符。它们当然得殿后啦,它们可是把前面的运算结果保存下来的必经之路。它们就如同慈爱的父母,默默地收拾前面这些孩子算出来的各种数据,并把它们认真地保存下来。我们的父母在我们小时候,不也是这样的吗?
咦?我们好像还漏一个,没错,逗号运算符。存在感太低啦!就放在最后一个吧!(我想你们大部分人也很少用它)。
这样我们的优先级就彻底理清楚啦!
总结一下:
分量、下标运算符、圆括号>单目运算符>算数运算符(五大金刚加两个小金刚)>关系运算符>位运算符(与或异或)>逻辑运算符(含条件运算符)>赋值运算符>逗号运算符
这个总结并不严谨,因为有些运算符并不是在一起的,所以要注意对我说的故事的理解,再结合表看看背背就OK了。
下面再说一下结合方向。
这个还是很好总结的,除了后缀自加自减的所有单目运算符、条件运算符、赋值运算符是右结合,其他的符号全是左结合。
这个还是很好理解的,那些单目运算符通常写在作用对象的左边,自然是从右向左结合,赋值符号也是把右边的数值赋给左边,所以也是从右向左,条件运算符……这么特殊的一个,记一下就好了。
这样我们就成功地解决了这张令人头疼的表。怎么样?不困难吧?

sizeof()的返回值问题

首先强调一下,这个不是函数,虽然它看起来很像。
它运算得到的值是括号内的东西所占的内存大小,它是一个int型的值。所以sizeof()的表达式是int型表达式。

函数相关

函数声明问题

我们知道C语言里是需要函数声明的,如果函数放在主调函数的后面,就需要在主调函数前进行原型声明。
但是不知道有没有像我一样,由于长期把函数放在主调函数的前面(少打几行字),而在考试时容易忘记声明这件事。其实网上有不少信息学竞赛题的代码,它们绝大多数都是把函数放在主调函数前面,所以这里也算是一个提醒吧。

mian函数参数问题

我们知道main函数有三个参数argc,argv,envp
我们主要提示一下前面两个。
现在如果我们在命令行执行如下语句:

D:\cgg.exe how are you!

这么执行后,argv是4,而不是3,因为D:\cgg.exe也是一个参数,而它就保存在argv[0]中。
这一点千万不能忘记。

变量相关

用字符串初始化字符数组

主要是长度的问题,我们知道C中的字符串是以一个空字符作为字符串的结尾标志。所以,我们在赋值时,要注意字符数组的长度要比字符串的长度多1。比如下面这段代码是无法通过编译的:

#includeint main(){    char a[4]="abcd";  return 0;}

而我们只需要把a的长度改为5就好了。

赋初值问题

这是一个老生常谈的问题,但是还是很容易被忽略。所以在这里再说一下。当遇到一些计算求值类的题,一定要注意把变量初始化,赋初值,比如0.

转义字符问题

我们知道C语言中是有转义字符的。转义字符以\开头,所以,我们是不能在一对单引号中间直接放置右斜杠的,还有就是注意,斜杠后如果是十六进制的表示码,开头是x或X,而不是0x或0X

常用ASCII码记忆

常用的无非是大小写字母和数字,这时一定需要记住的(除非你是上机考试)。

字符 ASCII值
A 65
a 97
0 48
CR(回车) 13
空格 32

字符串常量占用内存问题

我们知道C中的字符串一定是以空字符‘\0’结尾,而这个空字符是不显示的。所以有的出题老师会在这里设坑,比如:"abcde"占的内存大小是多少字节?虽然是五个字符,但是实际上还有一个空字符,总共是6字节。

字符变量值的问题

我们经常会遇到这样的题,问你某个字符的值是什么。
这时我们需要尤其小心,尤其是选择题。
我们举个例子来说:char a='C'
a的值是什么?
是C吗?
如果你说是,那就错了。
我们只能说a的值是‘C’或者67.
想必你应该能明白我想说什么了。
单引号是不能省去的,这一点尤其重要,缺少了单引号,它就不再是一个字符了。
这一点很容易忽略,尤其是选择题,看到C这个选项,一激动就选上了。那就惨了。

变量类型的范围计算问题

这里只提醒一点,计算范围的时候不要忘记对于有符号的数,有一位符号位。

字符串常量拼接问题

在C语言中是允许进行字符串拼接的。
也就是说,如果两对引号包含的字符串放在一起,则会被解释成一个字符串。
比如:

#includeint main(){    char a[15]="hello""world";   char b[15]="hel""lo""world";   printf("%s",b); return 0;}

这两个字符串都是合法的,且和“helloworld”等价。

数组相关

数组下标越界

这个……恐怕是个程序员都会出过的bug,从你初学编程语言到你退休。
考试也可能会出现这个问题,多半是在for循环里出现。

二维数组中行列计算问题

我们可能会经常看到这样的题,就是另一个指针等于二维数组中的某个地址单元,然后对指针进行加一之类的操作,然后问输出的值。
而我们知道这里会有两种不同的效果,一种是行计算,一种是列计算,二者的含义是,行计算,每次加一,地址会移动一行;而列计算,每次加一,地址只会移动一格。
比如:

#includeint main(int argc,char *argv[]){  char a[3][4]={{"you"},{"I"},{"we"}};   char (*p)[4]; p=a; printf("%s",*(p+1));   return 0;}

这里输出的就是第二个字符串I
具体的分类为:

类型 计算方式
a 计算行
&a[0][0] 计算列
a[0] 计算列
*a 计算列

字符数组赋值问题

我们知道我们可以这样声明一个字符数组:

char a[12]="helloworld!";

但是,字符数组在被定义之后,是不被允许这样直接赋值的
比如下面这段代码是不会通过编译的:

char a[12];

a="helloworld!";

结构体相关

结构体所包含的变量不可初始化

这一点在C++中是被允许的,但是C中是不允许的。
所以习惯了写C++的同学尤其需要注意。
不要忘记了。

查看结构体内部变量所占内存大小

这里我们只举个例子,比如我们有ABC这个结构体,它有变量x,
sizeof(((struct ABC*)0)->x)得到的就是x占用的内存大小。
这里的0,只要是int型的量就可以。

库函数相关

绝对值函数

注意math.h中有两个绝对值函数,一个是abs(),另一个是fabs()
其中前者是处理整型变量的,而后者是处理浮点型变量的

scanf()和printf()的返回值问题

我们通常会把它们当作输入输出语句使用,单独成行,总是自动忽略它们的返回值,但其实它们是有返回值的。
那么它们的返回值是什么呢?
printf的返回值是输出的数据个数,而scanf的返回值则是读入的数据个数。
我们可以来看个例题:

#includeint main(){    int x;    printf("2:%d",printf("1:%d,",scanf("%d",&x)));  return 0;

}

请问它的输出结果是什么?
答案是
1:1,2:4
为什么是4?不知道你是不是想这么问。
printf中所说的数据个数,其实是把输出的每个字符都看成一个单独的数据,也就是有多少字符加上我们传入的数据,就是它的返回值。

fclose()的返回值问题

和scanf、printf一样,我们经常忽略fclose的返回值,其实他也是有返回值的。
如果成功关闭流,那么返回0,如果未成功关闭则返回-1。

预编译相关

注意宏定义的替换原则

我们知道宏定义实际上只是字符串的替换,并不是函数一样的东西,所以我们在做题时也需要严格替换,替换完成之前,不要进行任何计算。
我们举个例子:

答案是多少?54?那就错了。实际上应该是48.
这里我们不能把5+1算出来6再带入,而是直接代入,这样你就会发现,5和1不是直接加在一起的。

免责声明:本文系网络转载,版权归原作者所有。如涉及作品版权问题,请我联系,感谢!

往期推荐好文

★C语言编程工具的选择

★求1000以内的水仙花数

★i++和++i有什么区别?

★「建议收藏」C语言编程判断回文数

★看完你就明白:什么情况下该用int main(int argc, char *argv[])而不是int     main(void)

★C语言编程:打印一个圆形

★福利:50本C语言电子书免费送了!

★C语言编程求解:1到1000之间所有的素数

★[必读]C语言学习者常见问题及回答

asin c语言中 返回值范围_大学C语言考试易错知识点总结相关推荐

  1. 大学C语言考试易错知识点总结

    文章目录 运算符相关 自增(减)前后缀 逻辑运算符的短路问题 赋值运算符的返回值问题 运算符优先级的问题 sizeof()的返回值问题 函数相关 函数声明问题 mian函数参数问题 变量相关 用字符串 ...

  2. asin c语言中 返回值范围_asin()_C语言asin()详解:反正弦函数,求反正弦值

    double asin(double x); asin() 函数的功能是求反正弦值. 反正弦函数 asin() 和正弦函数 sin() 的功能正好相反:sin() 是已知一个角的弧度值 x,求该角的正 ...

  3. asin c语言中 返回值范围_C语言asin()函数:求正弦值为 x 的弧度数

    函数名: asin 头文件: 函数原型: double asin(double x) 功 能: 求正弦值为 x 的弧度数 参数: double x    正弦值.x 的取值必须位于区间[-1, 1]中 ...

  4. c语言中初始值的作用,初始C语言学习

    一.我的第一个C语言程序 #include int main() { printf("Hello C语言!\n"); printf("Hello Word!\n" ...

  5. 统计学中p值计算公式_大学统计学白上了?800 多科学家联名反对 “统计学意义”,P 值该废了...

    [新智元导读]三位统计学家在 Nature 上发布公开信,号召科学家放弃追求 "统计学意义",这封公开信一周之内吸引了超过 800 名研究人员共同签署.大学里好不容易听懂的统计学, ...

  6. c语言函数返回值类型必须,C++中函数类型与定义的函数返回值类型必须相同么?...

    C++中函数类型与定义的函数返回值类型必须相同么?以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! C++中函数类型与定义 ...

  7. PHP允许输入负数,php exec在linux中返回值不能为负数

    php exec在linux中返回值不能为负数有需要的朋友可参考一下. 我们先来了解一下关于exec函数的使用方法 exec() 原型:  代码如下 复制代码 string exec (string ...

  8. 演示Go语言多返回值功能

    演示Go语言多返回值功能 Go语言革命性地在静态开发语言阵营中率先提供了多返回值功能.这个特性让开发者可以从原来用各种比较别扭的方式返回多个值的痛苦中解脱出来,既不用再区分参数列表中哪几个用于输入,哪 ...

  9. C语言return的用法详解,C语言函数返回值详解。 (本次转载仅供学习,感谢原创!!转发自C语言中文网,如有侵权请私信本人删除)

    C语言return的用法详解,C语言函数返回值详解 转载:http://c.biancheng.net/view/1855.html 函数的返回值是指函数被调用之后,执行函数体中的代码所得到的结果,这 ...

最新文章

  1. Android 抓包的一些命令 及 adb使用的一些注意事项
  2. hdu2063 二分图(基础题)
  3. Linux下的socket演示程序
  4. ArcGIS 10.2数字化线状要素时自动拼接成一条线
  5. 错误记录:Current request is not a multipart request
  6. mysql workbench for ubuntu测试
  7. (转) Arcgis for js加载百度地图
  8. 在java中对字符串的一些实现处理
  9. SQLite 事务控制
  10. python自动化测试-python自动化测试
  11. OpenCV-Python教程(10、直方图均衡化)
  12. java制作名片applet程序_【小程序 提取码:krua】壹佰智能名片小程序版本V1.1.45 – 持续更新 无后门...
  13. 蓝奏云自定义域名链接替换网站源码
  14. Spring boot项目 maven多模块打包,子模块报错问题解决
  15. 马王堆汉墓帛书‧老子——乙本释文(德经)
  16. 深度神经网络之Keras(二)——监督学习:回归
  17. 从零开始- Android刷机指南一
  18. 平面设计工作的8个基本技能
  19. java中extends和implements的区别
  20. 区块链基础理论与研究概况(前沿版)

热门文章

  1. 最小拍有纹波系统仿真实验matlab代码,最小拍控制器设计.doc
  2. C语言函数sscanf()的用法
  3. php echarts 两条曲线图,使用laravel和ECharts实现折线图效果的例子
  4. 硬盘物理序列号修改工具_精品软件:MHDD磁盘坏道扫描工具使用方法图解教程...
  5. python 笔试题 英方_经典算法题 :找字符串中的逆序对(百度笔试题)
  6. python监听多个udp端口_Python的Socket编程过程中实现UDP端口复用的实例分享
  7. python重复元素判定_20段极简Python代码:这些小技巧你都Get了么
  8. 系统接口502异常_基于SpringBoot2.0的后台权限管理系统
  9. np.random.seed的有效期及固定的种子会有固定的顺序
  10. **kw传参一个重要的细节