C语言K&R圣经笔记 2.4声明 2.5算术操作符 2.6关系和逻辑操作符

2.4 声明

所有变量在使用前必须声明,尽管某些特定的声明可以由上下文隐式地做出。声明指定了类型,并包含一个或多个该类型的变量列表,如

复制代码
int lower, upper, step;
char c, line[1000];

多个变量能以任何方式分布在多个声明之中;上面的列表可以等价地写成:

复制代码
int lower;
int upper;
int step;
char c;
char line[1000];

后面一种形式会占用更多空间,但在为每个声明增加注释或是做后续修改时,会很方便。

变量也可以在声明中初始化,如果名字后面跟着一个等号和一个表达式,则表达式作为初始化式(initializer),如

复制代码
char  esc = '\\';
int   i = 0;
int   limit = MAXLINE + 1;
float eps = 1.0e-5;

若该变量不是自动变量,则初始化只会做一次,从概念上来说是在程序执行之前,并且初始化式必须为常量表达式。显式初始化的自动变量,在每次进入其所在的函数或块的时候被初始化。外部和静态变量默认被初始化为0。未显式初始化的自动变量的值是未定义的(即垃圾值)。

修饰符 const 可用于任意变量的声明,以指明它的值不会改变。对数组而言,const 修饰符说明其元素不能被改变。

复制代码
const double e = 2.71828182845905;
const char msg[] = "warning: ";

const 声明也能与数组参数一同使用,以指示函数不会修改数组:

复制代码
int strlen(const char[]);

如果试图修改一个const,其结果是由实现定义的。

2.5 算术操作符

二元算术操作符包括加减乘除 +, -, *, /,以及取模操作符 % 。整数相除会截断小数部分。表达式

复制代码
x % y

得到 x 除以 y 的余数,而当 x 能被 y 整除时就为0。例如,闰年能被4整除而不能被100整除,除非可以被400整除。因此有:

复制代码
if ((year % 4 == 0 && y % 100 != 0) || y % 400 == 0)
    printf("%d is a leap year\n", year);
else
    printf("%d is not a leap year\n", year);

% 操作符不能用于 float 和 double。对于负数,除法 / 的截断方向 和 取模%结果的符号是依赖于机器的,正如发生了上溢和下溢时,所采取的操作也是依赖于机器的。

二元操作符 + 和 - 有相同的优先级,都比 * / 和 % 低,而它们又低于一元操作符正号和符号 + -。算术操作符从左到右结合。

本章结尾的表 2-1总结了所有操作符的优先级和结合性。

2.6 关系和逻辑操作符

关系操作符有

复制代码
    >    >=    <    <=

它们的优先级都相同。优先级仅次于它们的是相等性操作符:

复制代码
    ==    !=

关系操作符的优先级比算术操作符低,因此表达式如 i < lim - 1 就等于 i < (lim -1),符合大家的预期。

更有趣的是逻辑操作符 && 和 || 。由 && 或 || 连接的多个表达式是从左到右求值的,而且一旦结果的真假得到确定就会马上停止求值。大部分的C程序都依赖这两个特性。比如,下面这个循环来自第一章的读取输入的 getline 函数:

复制代码
for (i=0; i<lim-1 && (c=getchar()) != '\n' && c != EOF; ++i)
    s[i] = c;

在读入一个新字符之前,需要检查字符串 s 是否有空间,因此必须先测试 i < lim-1 。 而且如果测试失败,则不能继续读入下一个字符。

类似地,不能在调用getchar之前去检查 c 是否为EOF,因此调用getchar和对c赋值必须发生在检查字符c之前。

&& 的优先级比 || 高,而两者的优先级都低于关系和相等性操作符,因此表达式如

复制代码
 i<lim-1 && (c=getchar()) != '\n' && c != EOF

不需要多余的括号。但由于 != 的优先级高于赋值,因此下面的表达式需要括号

复制代码
    (c = getchar()) != '\n'

以保证先将值赋给c,再和'\n'进行比较。

根据定义,当关系为真时,关系和逻辑表达式的数值为1,当关系为假时值为0。

一元取反操作符 ! 将非0的操作数转换为0,将操作数0 转换为 1。操作符 ! 通常用在这样的结构中:

复制代码
if (!valid)

以取代

复制代码
if (valid == 0)

很难一概而论哪种形式更好。!valid 这种结构读起来更好("如果不合法"),但更复杂的结构会很让人难理解。

练习2-2,重写上面的for循环,但不用 && 和 ||

相关推荐
_Kayo_38 分钟前
node.js 学习笔记3 HTTP
笔记·学习
星星火柴9364 小时前
关于“双指针法“的总结
数据结构·c++·笔记·学习·算法
艾莉丝努力练剑5 小时前
【洛谷刷题】用C语言和C++做一些入门题,练习洛谷IDE模式:分支机构(一)
c语言·开发语言·数据结构·c++·学习·算法
Cx330❀7 小时前
【数据结构初阶】--排序(五):计数排序,排序算法复杂度对比和稳定性分析
c语言·数据结构·经验分享·笔记·算法·排序算法
小幽余生不加糖7 小时前
电路方案分析(二十二)适用于音频应用的25-50W反激电源方案
人工智能·笔记·学习·音视频
..过云雨8 小时前
01.【数据结构-C语言】数据结构概念&算法效率(时间复杂度和空间复杂度)
c语言·数据结构·笔记·学习
岑梓铭9 小时前
考研408《计算机组成原理》复习笔记,第五章(3)——CPU的【数据通路】
笔记·考研·408·计算机组成原理·计组
谱写秋天10 小时前
在STM32F103上进行FreeRTOS移植和配置(STM32CubeIDE)
c语言·stm32·单片机·freertos
我不是板神10 小时前
程序设计|C语言教学——C语言基础2:计算与控制语句
c语言
基于python的毕设10 小时前
C语言栈的实现
linux·c语言·ubuntu