Pointers on C——8 Arrays.1

来源:互联网 发布:数据采集方法 编辑:程序博客网 时间:2024/06/07 15:36

Youʹve been using simple, one‐dimensional arrays since Chapter 2. This chapter explains more about these arrays and explores more advanced array topics such as multidimensional arrays, arrays and pointers, and array initialization.

在第2 章,我们已经使用了一些简单的一维数组。本章我们将深入探讨数组,探索一些更加高级的数组话题如多维数组、数组和指针以及数组的初始化等。


8.1 One-Dimensional Arrays

Before we introduce multidimensional arrays, there is a lot more to learn about onedimensional arrays. Letʹs begin with a concept that many consider a flaw in the design of the C language, but this concept actually ties some disparate concepts together quite nicely.

在讨论多维数组之前,我们还需要学习很多关于一维数组的知识。首先让我们学习一个概念,它被许多人认为是C 语言设计的一个缺陷。但是,这个概念实际上以一种相当优雅的方式把一些完全不同的概念联系在一起的。


8.1.1 Array Names

Consider these declarations:

int a;

int b[10];


We call the variable a a scalar because it is a single value. The type of the value is integer. We call the variable b an array because it is a collection of values. A subscript is used with the array name to identify one specific value from that collection; for example, b[0] identifies the first value in the b array, and b[4] identifies the fifth. Each specific value is a scalar and may be used in any context in which a scalar may be used.

我们把变量a 称为标量,因为它是个单一的值,这个变量的类型是一个整数。我们把变量b 称为数组,因为它是一些值的集合。下标和数组名一起使用,用于标识该集合中某个特定的值。例如,b[0] 表示数组b 的第1 个值. b[4] 表示第5 个值。每个特定值都是一个标量,可以用于任何可以使用标量数据的上下文环境中。


The type of b[4] is integer, but what is the type of b? To what does it refer? A logical answer would be that it refers to the whole array, but it doesnʹt. In C, when the name of an array is used in almost any expression, the value of the name is a pointer constant that is the address of the first element of the array. Its type depends on the type of the array elements: if they are int, then the value of the array name is a ʺconstant pointer to int.ʺ If they are something else, then the value of the array name is a ʺconstant pointer to something else.ʺ

b[4] 的类型是整型,但b 的类型又是什么?它所表示的又是什么?一个合乎逻辑的答案是它表示整个数组,但事实并非如此。在C 中,在几乎所有使用数组名的表达式中,数组名的值是一个指针常量,也就是数组第1 个元素的地址。它的类型取决于数组元素的类型:如果它们是int 类型,那么数组名的类型就是“指向int的常量指针”;如果它们是其他类型,那么数组名的类型就是“指向其他类型的常量指针”。


Do not conclude from this that arrays and pointers are the same. An array has quite different characteristics than a pointer, for example, an array has a certain number of elements, while a pointer is a scalar. The compiler uses the array name to keep track of these properties. It is only when the array name is used in an expression that the compiler generates the pointer constant.

请不要根据这个事实得出数组和指针是相同的结论。数组具有一些和指针完全不同的特征。例如,数组具有确定数量的元素,而指针只是一个标量值。编译器用数组名来记住这些属性。只有当数组名在表达式中使用时,编译器才会为它产生一个指针常量。


Note‐that this value is a pointer constant as opposed to a pointer variable; you cannot change the value of a constant. On reflection this restriction makes sense; the value points to where the array begins in memory, so the only way to change it is to move the array somewhere else in memory. But memory for arrays is fixed when the program is linked, so by the time the program is running, it is much too late to move an array. Hence, the values of array names are pointer constants.

注意这个值是指针常量,而不是指针变量。你不能修改常量的值。你只要稍微回想一下,就会认为这个限制是合理的:指针常量所指向的是内存中数组的起始位置,如果修改这个指针常量,唯一可行的操作就是把整个数组移动到内存的其他位置。但是,在程序完成链接之后,内存中数组的位置是固定的,所以当程序运行时,再想移动数组就为时己晚了。因此,数组名的值是一个指针常量。


There are only two places where this pointer substitution does not occur—when an array name is an operand of either sizeof or the unary operator &. sizeof returns the size of the entire array, not the size of a pointer to the array. Taking the address of an array name gives a pointer to the first element in the array, not a pointer to some substituted pointer constant value.

只有在两种场合下,数组名并不用指针常量来表示——就是当数组名作为sizeof 操作符或单目操作符&的操作数时。sizeof 返回整个数组的长度,而不是指向数组的指针的长度。取一个数组名的地址所产生的是一个指向数组第一个元素的指针,而不是一个指向某个指针常量值的指针


Now consider this example:

int a[10];

int b[10];

int *c;

...

c = &a[0];


The expression &a[0] is a pointer to the first element of the array. But thatʹs the value of the array name itself, so the following assignment performs exactly the same job as the one above:

表达式&a[0] 是一个指向数组第1 个元素的指针。但那正是数组名本身的值,所以下面这条赋值语句和上面那条赋值语句所执行的任务是完全一样的:


c = a;


This assignment shows why it is important to understand the true meaning of an array name in an expression. If the name referred to the entire array, this statement would imply that the entire array is being copied to a new array. But this is not at all what happens; what is assigned is a copy of a pointer, making c point to the first element of the array. Thus, assignments such as

这条赋值语句说明了为什么理解表达式中的数组名的真正含义是非常重要的。如果数组名表示整个数组,这条语句就表示整个数组被复制到一个新的数组。但事实上完全不是这样,实际被赋值的是一个指针的拷贝, c 所指向的是数组的第1 个元素。因此,像下面这样的表达式:


b = a;


are illegal. You cannot use the assignment operator to copy all the elements of one array to another array; you must use a loop and copy one element at a time.

是非法的。你不能使用赋值符把一个数组的所有元素复制到另一个数组。你必须使用一个循环,每次复制一个元素。


Consider this statement:

a = c;


With c declared as a pointer variable, this assignment looks like it ought to perform another pointer assignment, copying the value of c into a. But this assignment is illegal: remember that the value of a in this expression is a constant, so it cannot be changed.

c 被声明为一个指针变量,这条语句看上去像是执行某种形式的指针赋值,把c 的值复制给a 。但这个赋值是非法的:记住!在这个表达式中, a 的值是个常量,不能被修改。

上一章 Pointers on C——7 Functions.10

原创粉丝点击