Chapter 2

来源:互联网 发布:我的战争预告片知乎 编辑:程序博客网 时间:2024/06/05 05:05

2.8 Increment and Decrement Operators

C provides two unusual operators for incrementing and decrementing variables. The increment operator ++ adds 1 to its operand, while the decrement operator -- subtracts 1. We have frequently used ++ to increment variables, as in

C语言提供了两个用于变量递增与递减的特殊运算符。自增运算符++使其操作数递增1,自减运算符使其操作数递减1。我们经常使用++运算符递增变量的值,如下所示:

if (c == '\n')

++nl;


The unusual aspect is that ++ and -- may be used either as prefix operators (before the variable, as in ++n), or postfix operators (after the variable: n++). In both cases, the effect is to increment n. But the expression ++n increments n before its value is used, while n++ increments n after its value has been used. This means that in a context where the value is being used, not just the effect, ++n and n++ are different. If n is 5, then

++--这两个运算符特殊的地方主要表现在:它们既可以用作前缀运算符(用在变量前面,如++n)。也可以用作后缀运算符(用在变量后面,如n++)。在这两种情况下,其效果都是将变量n的值加1。但是,它们之间有一点不同。表达式++n先将n的值递增1,然后再使用变量n 的值,而表达式n++则是先使用变量n 的值,然后再将n 的值递增1。也就是说,对于使用变量n的值的上下文来说,++nn++的效果是不同的。如果n的值为5,那么


x = n++;

sets x to 5, but

x = ++n;


sets x to 6. In both cases, n becomes 6. The increment and decrement operators can only be applied to variables; an expression like (i+j)++ is illegal.

x的值置为6。这两条语句执行完成后,变量n的值都是6。自增与自减运算符只能作用于变量,类似于表达式(i+j)++是非法的。


In a context where no value is wanted, just the incrementing effect, as in

在不需要使用任何具体值且仅需要递增变量的情况下,前缀方式和后缀方式的效果相同。例如:

 

if (c == '\n')

nl++;


prefix and postfix are the same. But there are situations where one or the other is specifically called for. For instance, consider the function squeeze(s,c), which removes all occurrences of the character c from the string s.

但在某些情况下需要酌情考虑。例如,考虑下面的函数squeeze(s, c),它删除字符串s中出现的所有字符c

 

/* squeeze: delete all c from s */

void squeeze(char s[], int c)

{

int i, j;

for (i = j = 0; s[i] != '\0'; i++)

if (s[i] != c)

s[j++] = s[i];

s[j] = '\0';

}


Each time a non-c occurs, it is copied into the current j position, and only then is j incremented to be ready for the next character. This is exactly equivalent to

每当出现一个不是c 的字符时,该函数把它拷贝到数组中下标为j 的位置,随后才将j 的值增加1,以准备处理下一个字符。其中的if语句完全等价于下列语句:

 

if (s[i] != c) {

s[j] = s[i];

j++;

}


Another example of a similar construction comes from the getline function that we wrote in Chapter 1, where we can replace

我们在第1章中编写的函数getline是类似结构的另外一个例子。我们可以将该函数中的if语句:用下面这种更简洁的形式代替:

 

if (c == '\n') {

s[i] = c;

++i;

}

by the more compact

if (c == '\n')

s[i++] = c;


As a third example, consider the standard function strcat(s,t), which concatenates the string t to the end of string s. strcat assumes that there is enough space in s to hold the combination. As we have written it, strcat returns no value; the standard library version returns a pointer to the resulting string.

我们再来看第三个例子。考虑标准函数strcat(s, t),它将字符串t 连接到字符串s的尾部。函数strcat 假定字符串s 中有足够的空间保存这两个字符串连接的结果。下面编写的这个函数没有任何返回值(标准库中的该函数返回一个指向新字符串的指针):


/* strcat: concatenate t to end of s; s must be big enough */

void strcat(char s[], char t[])

{ 46

int i, j;

i = j = 0;

while (s[i] != '\0') /* find end of s */

i++;

while ((s[i++] = t[j++]) != '\0') /* copy t */

;

}


As each member is copied from t to s, the postfix ++ is applied to both i and j to make sure that they are in position for the next pass through the loop.

 在将t中的字符逐个拷贝到s的尾部时,变量ij使用的都是后缀运算符++,从而保证在循环过程中ij均指向下一个位置。

2.9 Bitwise Operators

 

C provides six operators for bit manipulation; these may only be applied to integral operands, that is, char, short, int, and long, whether signed or unsigned.

C语言提供了6个位操作运算符。这些运算符只能作用于整型操作数,即只能作用于带符号或无符号charshortintlong类型:

 

& bitwise AND 按位与(AND)

 

|    bitwise inclusive OR 按位或(OR)

 

^   bitwise exclusive OR 按位异或(XOR)

 

<<  left shift 左移

 

>>  right shift 右移

 

~ one's complement (unary) 按位求反(一元运算符)












The bitwise AND operator & is often used to mask off some set of bits, for example

按位与运算符&经常用于屏蔽某些二进制位,例如: 

n = n & 0177;

sets to zero all but the low-order 7 bits of n.

该语句将n中除7个低二进制位外的其它各位均置为0 

The bitwise OR operator | is used to turn bits on:

按位或运算符|常用于将某些二进制位置为1,例如: 

x = x | SET_ON;


sets to one in x the bits that are set to one in SET_ON.

该语句将x中对应于SET_ON中为1 的那些二进制位置为1 

The bitwise exclusive OR operator ^ sets a one in each bit position where its operands have different bits, and zero where they are the same.

按位异或运算符^当两个操作数的对应位不相同时将该位设置为1,否则,将该位设置为0 


One must distinguish the bitwise operators & and | from the logical operators && and ||, which imply left-to-right evaluation of a truth value. For example, if x is 1 and y is 2, then x & y is zero while x && y is one.

我们必须将位运算符&|同逻辑运算符&&||区分开来,后者用于从左至右求表达式的真值。例如,如果x的值为1Y的值为2,那么,x & y的结果为0,而x && y 的值为1


The shift operators << and >> perform left and right shifts of their left operand by the number of bit positions given by the right operand, which must be non-negative. Thus x << 2 shifts the value of x by two positions, filling vacated bits with zero; this is equivalent to multiplication by 4. Right shifting an unsigned quantity always fits the vacated bits with zero. Right shifting a signed quantity will fill with bit signs (``arithmetic shift'') on some machines and with 0-bits (``logical shift'') on others.

移位运算符<<>>分别用于将运算的左操作数左移与右移,移动的位数则由右操作数指定(右操作数的值必须是非负值)。因此,表达式x << 2 将把x 的值左移2 位,右边空出的2 位用0 填补,该表达式等价于对左操作数乘以4。在对unsigned类型的无符号值进行右移位时,左边空出的部分将用0 填补;当对signed 类型的带符号值进行右移时,某些机器将对左边空出的部分用符号位填补(即“算术移位”),而另一些机器则对左边空出的部分用0填补(即“逻辑移位”)。


The unary operator ~ yields the one's complement of an integer; that is, it converts each 1-bit into a 0-bit and vice versa. For example

一元运算符~用于求整数的二进制反码,即分别将操作数各二进制位上的1 变为00 变为1。例如:

x = x & ~077


sets the last six bits of x to zero. Note that x & ~077 is independent of word length, and is thus preferable to, for example, x & 0177700, which assumes that x is a 16-bit quantity. The portable form involves no extra cost, since ~077 is a constant expression that can be evaluated at compile time.

将把x的最后6位设置为0。注意,表达式x & ~077与机器字长无关,它比形式为x & 0177700的表达式要好,同为后者假定x16位的数值。这种可移植的形式并没有增加额外开销,因为,~077是常量表达式,可以在编译时求值。

 

As an illustration of some of the bit operators, consider the function getbits(x,p,n) that returns the (right adjusted) n-bit field of x that begins at position p. We assume that bit position 0 is at the right end and that n and p are sensible positive values. For example, getbits(x,4,3) returns the three bits in positions 4, 3 and 2, right-adjusted.

为了进一步说明某些位运算符,我们来看函数getbits(x, p, n),它返回x中从右边数第p位开始向右数n位的字段。这里假定最右边的一位是第0位,np都是合理的正值。

例如,getbits(x, 4, 3)返回x中第432三位的值。


/* getbits: get n bits from position p */

unsigned getbits(unsigned x, int p, int n)

{

return (x >> (p+1-n)) & ~(~0 << n);

}

The expression x >> (p+1-n) moves the desired field to the right end of the word. ~0 is all 1-bits; shifting it left n positions with ~0<<n places zeros in the rightmost n bits; complementing that with ~ makes a mask with ones in the rightmost n bits.

其中,表达式m << (p+1-n)将期望获得的字段移位到字的最右端。~0的所有位都为1,这里使用语句~0 << n ~0左移n位,并将最右边的n位用0 填补。再使用~运算对它按位取反,这样就建立了最右边n位全为1 的屏蔽码。




 

increment n.增量,加1

Decrement 减量,减1

















原创粉丝点击