Chapter 2

来源:互联网 发布:ubuntu和windows比较 编辑:程序博客网 时间:2024/05/22 11:46

2.4 Declarations

All variables must be declared before use, although certain declarations can be made implicitly by content. A declaration specifies a type, and contains a list of one or more variables of that type, as in

所有变量都必须先声明后使用,尽管某些变量可以通过上下文隐式地声明。一个声明指定一种变量类型,后面所带的变量表可以包含一个或多个该类型的变量。例如:

 

int lower, upper, step;

char c, line[1000];


Variables can be distributed among declarations in any fashion; the lists above could well be written as

一个声明语句中的多个变量可以拆开在多个声明语句中声明。上面的两个声明语句也可以等价地写成下列形式:

 

int lower;

int upper;

int step;

char c;

char line[1000];


The latter form takes more space, but is convenient for adding a comment to each declaration for subsequent modifications.

按照这种形式书写代码需要占用较多的空间,但便于向各声明语句中添加注释,也便于以后修改。

 

A variable may also be initialized in its declaration. If the name is followed by an equals sign and an expression, the expression serves as an initializer, as in

还可以在声明的同时对变量进行初始化。在声明中,如果变量名的后面紧跟一个等号以及一个表达式,该表达式就充当对变量进行初始化的初始化表达式。例如:

 

char esc = '\\';

int i = 0;

int limit = MAXLINE+1;

float eps = 1.0e-5;

 

If the variable in question is not automatic, the initialization is done once only, conceptionally before the program starts executing, and the initializer must be a constant expression. An explicitly initialized automatic variable is initialized each time the function or block it is in is entered; the initializer may be any expression. External and static variables are initialized to zero by default. Automatic variables for which is no explicit initializer have undefined (i.e., garbage) values.

如果变量不是自动变量,则只能进行一次初始化操作,从概念上讲,应该是在程序开始执行之前进行,并且初始化表达式必须为常量表达式。每次进入函数或程序块时,显式初始化的自动变量都将被初始化一次,其初始化表达式可以是任何表达式。默认情况下,外部变量与静态变量将被初始化为0。未经显式初始化的自动变量的值为未定义值(即无效值)。

The qualifier const can be applied to the declaration of any variable to specify that its value will not be changed. For an array, the const qualifier says that the elements will not be altered.

任何变量的声明都可以使用const限定符限定。该限定符指定变量的值不能被修改。对数组而言,const限定符指定数组所有元素的值都不能被修改:

const double e = 2.71828182845905;

const char msg[] = "warning: ";

The const declaration can also be used with array arguments, to indicate that the function does not change that array:

const限定符也可配合数组参数使用,它表明函数不能修改数组元素的值:

int strlen(const char[]); 

The result is implementation-defined if an attempt is made to change a const.

如果试图修改const限定符限定的值,其结果取决于具体的实现。

 

2.5 Arithmetic Operators

The binary arithmetic operators are +, -, *, /, and the modulus operator %. Integer division truncates any fractional part. The expression

二元算术运算符包括:+-*/%(取模运算符)。整数除法会截断结果中的小数部分。表达式

x % y

produces the remainder when x is divided by y, and thus is zero when y divides x exactly. For example, a year is a leap year if it is divisible by 4 but not by 100, except that years divisible by 400 are leap years. Therefore

的结果是x 除以y 的余数,当x 能被y 整除时,其值为0。例如,如果某一年的年份能被4整除但不能被100整除,那么这一年就是闰年,此外,能被400整除的年份也是闰年。因此,可以用下列语句判断闰年:

if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)

     printf("%d is a leap year\n", year);

else

     printf("%d is not a leap year\n", year);

The % operator cannot be applied to a float or double. The direction of truncation for / and the sign of the result for % are machine-dependent for negative operands, as is the action taken on overflow or underflow.

取模运算符%不能应用于float double 类型。在有负操作数的情况下,整数除法截取的方向以及取模运算结果的符号取决于具体机器的实现,这和处理上溢或下溢的情况是一样的。

The binary + and - operators have the same precedence, which is lower than the precedence of *, / and %, which is in turn lower than unary + and -. Arithmetic operators associate left to right.

二元运算符+-具有相同的优先级,它们的优先级比运算符*/%的优先级低,而运算符*/%的优先级又比一元运算符+-的优先级低。算术运算符采用从左到右的结合规则。


2.6 Relational and Logical Operators

The relational operators are

> >= < <=

They all have the same precedence. Just below them in precedence are the equality operators:

它们具有相同的优先级。优先级仅次于它们的是相等性运算符:

 

== !=

Relational operators have lower precedence than arithmetic operators, so an expression like i < lim-1 is taken as i < (lim-1), as would be expected.

关系运算符的优先级比算术运算符低。因此,表达式i < lim - 1 等价于i < (lim - 1)

More interesting are the logical operators && and ||. Expressions connected by && or || are evaluated left to right, and evaluation stops as soon as the truth or falsehood of the result is known. Most C programs rely on these properties. For example, here is a loop from the input function getline that we wrote in Chapter 1:

逻辑运算符&&||有一些较为特殊的属性,由&&||连接的表达式按从左到右的顺序进行求值,并且,在知道结果值为真或假后立即停止计算。绝大多数C 语言程序运用了这些属性。例如,下列在功能上与第1 章的输入函数getline中的循环语句等价的循环语句:

for (i=0; i < lim-1 && (c=getchar()) != '\n' && c != EOF; ++i)

s[i] = c;

Before reading a new character it is necessary to check that there is room to store it in the array s, so the test i < lim-1 must be made first. Moreover, if this test fails, we must not go on and read another character.

在读入一个新字符之前必须先检查数组s 中足否还有空间存放这个字符,因此必须首先测试条件i<lim-1。如果这一测试失败,就没有必要继续读入下一字符。

Similarly, it would be unfortunate if c were tested against EOF before getchar is called; therefore the call and assignment must occur before the character in c is tested.

类似地,如果在调用getchar函数之前就测试c是否为EOF,结果也是不正确的,因此,函数的调用与赋值都必须在对c中的字符进行测试之前进行。

The precedence of && is higher than that of ||, and both are lower than relational and equality operators, so expressions like

运算符&&的优先级比||的优先级高,但两者都比关系运算符和相等性运算符的优先级低。因此,表达式

 

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

need no extra parentheses. But since the precedence of != is higher than assignment, parentheses are needed in

就不需要另外加圆括号。但是,由于运算符!=的优先级高于赋值运算符的优先级,因此,在表达式

 

(c=getchar()) != '\n'

to achieve the desired result of assignment to c and then comparison with '\n'.

中,就需要使用圆括号,这样才能达到预期的目的:先把函数返回值赋值给c,然后再将c'\n'进行比较。

 

By definition, the numeric value of a relational or logical expression is 1 if the relation is true, and 0 if the relation is false.

根据定义,在关系表达式或逻辑表达式中,如果关系为真,则表达式的结果值为数值1如果为假,则结果值为数值0

 

The unary negation operator ! converts a non-zero operand into 0, and a zero operand in 1. A common use of ! is in constructions like

逻辑非运算符!的作用是将非0 操作数转换为0,将操作数0 转换为1。该运算符通常用于下列类似的结构中:

 

if (!valid)

rather than

if (valid == 0)

It's hard to generalize about which form is better. Constructions like !valid read nicely (``if not valid''), but more complicated ones can be hard to understand.

当然,很难评判上述两种形式哪种更好。类似于!valid 的用法读起来更直观一些(“如果不是有效的”),但对于一些更复杂的结构可能会难于理解。


原创粉丝点击