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循环,但不用 && 和 ||

相关推荐
就爱学编程1 小时前
重生之我在异世界学编程之C语言小项目:通讯录
c语言·开发语言·数据结构·算法
oneouto1 小时前
selenium学习笔记(二)
笔记·学习·selenium
sealaugh321 小时前
aws(学习笔记第十九课) 使用ECS和Fargate进行容器开发
笔记·学习·aws
北国无红豆2 小时前
【CAN总线】STM32的CAN外设
c语言·stm32·嵌入式硬件
单片机学习之路2 小时前
【C语言】结构
c语言·开发语言·stm32·单片机·51单片机
LuH11243 小时前
【论文阅读笔记】Scalable, Detailed and Mask-Free Universal Photometric Stereo
论文阅读·笔记
graceyun3 小时前
C语言初阶习题【9】数9的个数
c语言·开发语言
m0_748256785 小时前
WebGIS实战开源项目:智慧机场三维可视化(学习笔记)
笔记·学习·开源
红色的山茶花5 小时前
YOLOv9-0.1部分代码阅读笔记-loss.py
笔记
Schwertlilien5 小时前
图像处理-Ch5-图像复原与重建
c语言·开发语言·机器学习