Chapter 4 - Functions and Program Structure(四)

​4.7 Register Variables

A register declaration advises the compiler that the variable in question will be heavily used. The idea is that register variables are to be placed in machine registers, which may result in smaller and faster programs. But compilers are free to ignore the advice.

register 声明告诉编译器,它所声明的变量在程序中使用频率较高。其思想是,将register 变量放在机器的寄存器中,这样可以使程序更小、执行速度更快。但编译器可以忽略此选项。

The register declaration looks like

register int x;

register char c;

and so on. The register declaration can only be applied to automatic variables and to the formal parameters of a function. In this later case, it looks like

register声明只适用于自动变量以及函数的形式参数。下面是后一种情况的例子:

f(register unsigned m, register long n)

{

register int i;

...

}

In practice, there are restrictions on register variables, reflecting the realities of underlying hardware. Only a few variables in each function may be kept in registers, and only certain types are allowed. Excess register declarations are harmless, however, since the word register is ignored for excess or disallowed declarations. And it is not possible to take the address of a register variable (a topic covered in Chapter 5), regardless of whether the variable is actually placed in a register. The specific restrictions on number and types of register variables vary from machine to machine.

实际使用时,底层硬件环境的实际情况对寄存器变量的使用会有一些限制。每个函数中只有很少的变量可以保存在寄存器中,且只允许某些类型的变量。但是,过量的寄存器声明并没有什么害处,这是因为编译器可以忽略过量的或不支持的寄存器变量声明。另外,无论寄存器变量实际上是不是存放在寄存器中,它的地址都是不能访问的(有关这一点更详细的信息,我们将在第5章中讨论)。在不同的机器中,对寄存器变量的数目和类型的具体限制也是不同的。


4.8 Block Structure

C is not a block-structured language in the sense of Pascal or similar languages, because functions may not be defined within other functions. On the other hand, variables can be defined in a block-structured fashion within a function. Declarations of variables (including initializations) may follow the left brace that introduces any compound statement, not just the one that begins a function. Variables declared in this way hide any identically named variables in outer blocks, and remain in existence until the matching right brace. For example, in

C语言并不是Pascal等语言意义上的程序块结构的语言,它不允许在函数中定义函数。但是,在函数中可以以程序块结构的形式定义变量。变量的声明(包括初始化)除了可以紧跟在函数开始的花括号之后,还可以紧跟在任何其它标识复合语句开始的左花括号之后。以这种方式声明的变量可以隐藏程序块外与之同名的变量,它们之间没有任何关系,并在与左花括号匹配的右花括号出现之前一直存在。例如,在下面的程序段中:

if (n > 0) {

int i; /* declare a new i */

for (i = 0; i < n; i++)

...

}

the scope of the variable i is the ``true'' branch of the if; this i is unrelated to any i outside the block. An automatic variable declared and initialized in a block is initialized each time the block is entered.

变量i 的作用域是if 语句的“真”分支,这个i 与该程序块外声明的i 无关。每次进入程序块时,在程序块内声明以及初始化的自动变量都将被初始化。静态变量只在第一次进入程序块时被初始化一次。

Automatic variables, including formal parameters, also hide external variables and functions of the same name. Given the declarations

自动变量(包括形式参数)也可以隐藏同名的外部变量与函数。在下面的声明中:

int x;

int y;

f(double x)

{

double y;

}

then within the function f, occurrences of x refer to the parameter, which is a double; outside f, they refer to the external int. The same is true of the variable y.

函数f 内的变量x 引用的是函数的参数,类型为double;面在函数f 外,xint 类型的外部变量。这段代码中的变量y也是如此。

As a matter of style, it's best to avoid variable names that conceal names in an outer scope; the potential for confusion and error is too great.

在一个好的程序设计风格中,应该避免出现变量名隐藏外部作用域中相同名字的情况,否则,很可能引起混乱和错误。


4.9 Initialization

Initialization has been mentioned in passing many times so far, but always peripherally to some other topic. This section summarizes some of the rules, now that we have discussed the various storage classes.

前面我们多次提到过初始化的概念,不过始终没有详细讨论。本节将对前面讨论的各种存储类的初始化规则做一个总结。

In the absence of explicit initialization, external and static variables are guaranteed to be initialized to zero; automatic and register variables have undefined (i.e., garbage) initial values.

在不进行显式初始化的情况下,外部变量和静态变量都将被初始化为0,而自动变量和寄存器变量的初值则没有定义(即初值为无用的信息)。

Scalar variables may be initialized when they are defined, by following the name with an equals sign and an expression:

定义标量变量时,可以在变量名后紧跟一个等号和一个表达式来初始化变量:

int x = 1;

char squota = '\'';

long day = 1000L * 60L * 60L * 24L; /* milliseconds/day */

For external and static variables, the initializer must be a constant expression; the initialization is done once, conceptionally before the program begins execution. For automatic and register variables, the initializer is not restricted to being a constant: it may be any expression involving previously defined values, even function calls. For example, the initialization of the binary search program in Section 3.3 could be written as

对于外部变量与静态变量来说,初始化表达式必须是常量表达式,且只初始化一次(从概念上讲是在程序开始执行前进行初始化)。对于自动变量与寄存器变量,则在每次进入函数或程序块时都将被初始化。

int binsearch(int x, int v[], int n)

{

int low = 0;

int high = n - 1;

int mid;

...

}

instead of

int low, high, mid;

low = 0;

high = n - 1;

In effect, initialization of automatic variables are just shorthand for assignment statements. Which form to prefer is largely a matter of taste. We have generally used explicit assignments, because initializers in declarations are harder to see and further away from the point of use.

实际上,自动变量的初始化等效于简写的赋值语句。究竟采用哪一种形式,还得看个人的习惯。考虑到变量声明中的初始化表达式容易被人忽略,且距使用的位置较远,我们一般使用显式的赋值语句。

An array may be initialized by following its declaration with a list of initializers enclosed in braces and separated by commas. For example, to initialize an array days with the number of days in each month:

数组的初始化可以在声明的后面紧跟一个初始化表达式列表,初始化表达式列表用花括号括起来,各初始化表达式之间通过逗号分隔。例如,如果要用一年中各月的天数初始化数组days,其变量的定义如下:

int days[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }

When the size of the array is omitted, the compiler will compute the length by counting the initializers, of which there are 12 in this case.

当省略数组的长度时,编译器将把花括号中初始化表达式的个数作为数组的长度,在本例中数组的长度为12

If there are fewer initializers for an array than the specified size, the others will be zero for external, static and automatic variables. It is an error to have too many initializers. There is no way to specify repetition of an initializer, nor to initialize an element in the middle of an array without supplying all the preceding values as well.

如果初始化表达式的个数比数组元索数少,则对外部变量、静态变量和自动变量来说,没有初始化表达式的元素将被初始化为0,如果初始化表达式的个数比数组元素数多,则是错误的。不能一次将一个初始化表达式指定给多个数组元素,也不能跳过前面的数组元素而直接初始化后面的数组元素。

Character arrays are a special case of initialization; a string may be used instead of the braces and commas notation:

字符数组的初始化比较特殊:可以用一个字符串来代替用花括号括起来并用逗号分隔的初始化表达式序列。例如:

char pattern = "ould";

is a shorthand for the longer but equivalent

char pattern[] = { 'o', 'u', 'l', 'd', '\0' };

In this case, the array size is five (four characters plus the terminating '\0').

这种情况下,数组的长度是54 个字符加上一个字符串结束符'\0')。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值