c语言数组
c语言-数组
例1.3 选择排序
• 对一组数据{88, 84, 83, 87, 61}按从小到大
的顺序排序后输出。 61 83
i=1 k=2
84
87
88
j=4
i != k:交换a[i]与a[k]
西北农林科技大学
例1.3 选择排序
• 对一组数据{88, 84, 83, 87, 61}按从小到大
的顺序排序后输出。 61 83 84
83
87
61
84 < 88
西北农林科技大学
例1.3 选择排序
• 对一组数据{88, 84, 83, 87, 61}按从小到大
的顺序排序后输出。 88
i=0
84
83
j=2 k=2
87
61
83 < 84
西北农林科技大学
例1.3 选择排序
• 对一组数据{88, 84, 83, 87, 61}按从小到大
• for (i=0; i<10; i++) printf(“%d”, a[i]);
若数组下标<0或>=n,将出现数组下标越界的问题, 此类问题编译器可能不会给出错误提示。
西北农林科技大学
1.3 数组下标
• 为便于修改,采用宏(define)预先定义数组
元素个数。
• #define N 9 • int a[N] = {3,4,1,4,5,6,8,0,2};
的顺序排序后输出。 88
i=0 k=2
84
83
87
j=3
61
87 > 83:k不变
西北农林科技大学
例1.3 选择排序
• 对一组数据{88, 84, 83, 87, 61}按从小到大
c语言中的数组定义
c语言中的数组定义
在C语言中,数组是一种存储固定大小同类型元素的集合的数据结构。
数组的定义通常包括以下部分:
1. 数组的名称:这是一个标识符,用于标识数组。
2. 数组的元素类型:这是数组中元素的数据类型。
3. 数组的大小:这是数组中元素的数量。
数组的声明示例如下:
```c
int array[5]; // 定义一个名为 array 的整型数组,包含5个元素。
```
在这个例子中,`int` 是元素的数据类型,`array` 是数组的名称,`5` 是数组的大小。
您也可以在声明的同时初始化数组:
```c
int array[5] = {1, 2, 3, 4, 5}; // 定义并初始化一个整型数组
```
在这个例子中,数组 `array` 被初始化为五个整数值。
注意,C语言中的数组索引是从0开始的。
因此,上述数组 `array` 的五个元素可以通过索引 `0` 到 `4` 来访问。
例如,`array[0]` 将返回 `1`,
`array[4]` 将返回 `5`。
c语言里的数组
c语言里的数组
数组是C语言中的一种构造数据类型,是一组类型相同的数据元素的集合,这些元素会顺序地储存在内存的某段区域。
数组的特点有:
- 数组是一种引用类型数据,存放在内存中。
- 数组当中存放多个数据(元素),类型必须统一。
(如果定义的是int类型,那么里面的所有元素都必须是int类型)
数组的定义语法为:
```c
数组类型数组名(数组大小)
```
其中,数组大小决定了数组中能够存放的元素数量。
数组大小不能是变量,只能是字面值或字面值表达式。
并且,C语言编译器要求在编译期间就需要确定数组的内存大小,数组大小必须是大于0的正整数。
C语言 第六章 数组
6
6.1 排序问题
3. 初始化
类型名 数组名[数组长度]={初值表}; 初值表中依次放着数组元素的初值。例如: int a[10]={1,2,3,4,5,6,7,8,9,10}; 静态存储的数组如果没有初始化,系统自动给所有的数组元素赋0。 即 static int b[5]; 等价于 static int b[5]={0,0,0,0,0}; 初始化也可以只针对部分元素,如 static int b[5]={1,2,3}; 只对数组b的前3个元素赋初值,其余元素的初值为0。又如 int f[20]={0,1}; 对数组f的前两个元素赋初值,其余元素的值 不确定。
18
6.2 矩阵中最大值的位置
4. 使用二维数组编程
例7:定义一个3*2的二维数组a,数组元素的值由下式给 出,按矩阵的形式输出a。a[i][j]=i+j(0≤i ≤2, 0≤j ≤1), 见文件p131ex7-6.cpp
i
j
第1次 第2次 第3次 第4次 第5次
第6次
0 0 1 1 2
2
0 1 0 1 0
9
6.1 排序问题
4. 使用一维数组编程
例4:输入一个正整数n(1<n≤10), 再输入n个整数,将它们存入 数组a中。 ① 输出最小值和它所对应的下标。 ② 将最小值与第一个数交换,输 出交换后的n个数。 数组的长度在定义时必须确定, 如果无法确定需要处理的数据 数量,至少也要估计其上限, 并将该上限值作为数组长度。 因为n ≤10,数组长度就取上 限10。此外,如果用变量 index记录最小值对应的下标, 则最小值就是a[index]。 见p124ex7-4.cpp
8
6.1 排序问题
4. 使用一维数组编程
C语言数组了解数组的定义和使用
C语言数组了解数组的定义和使用C语言数组:了解数组的定义和使用数组是C语言中一种重要的数据结构,它可以用于存储一系列相同类型的元素。
在本篇文章中,将详细介绍C语言数组的定义和使用方法。
一、数组的定义数组的定义需要指定元素类型和数组的大小。
以下是一个基本的数组定义的语法:```c数据类型数组名[数组大小];```其中,数据类型表示数组中元素的类型,数组名是数组的标识符,而数组大小指定了数组中元素的个数。
例如,下面的代码展示了一个包含5个整数的数组的定义:```cint numbers[5];```这样就定义了一个名为numbers的整型数组,它可以存储5个整数。
二、数组的使用1. 初始化数组在定义数组的同时,可以对数组进行初始化。
对数组进行初始化可以通过多种方式实现。
1.1 直接初始化可以使用花括号{}来直接初始化数组元素,每个元素之间使用逗号分隔。
例如:```cint numbers[5] = {1, 2, 3, 4, 5};```这样就将数组numbers的前5个元素分别初始化为1、2、3、4、5。
1.2 部分初始化也可以只对数组的部分元素进行初始化。
未初始化的元素将被自动设置为0。
例如:```cint numbers[5] = {1, 2, 3};```这样就将数组numbers的前3个元素分别初始化为1、2、3,而后面两个元素将被设置为0。
1.3 不初始化数组也可以不进行初始化,此时数组的元素将是未知的随机值。
例如:```cint numbers[5];```这样就创建了一个名为numbers的整型数组,但它的元素值是未知的。
2. 访问数组元素可以使用数组名和索引来访问数组中的元素。
数组索引从0开始,依次递增。
例如:```cint number = numbers[2];```这样就将数组numbers中索引为2的元素的值赋给了整型变量number。
3. 修改数组元素通过使用数组名和索引,可以修改数组中的元素的值。
c语言中数组的概念
在C语言中,数组是一种用于存储相同类型的多个元素的数据结构。
数组提供了一种有序、连续的内存存储方式,通过索引(下标)来访问单个元素。
以下是关于C语言中数组的一些基本概念:1. **声明数组:** 在C语言中,你可以使用以下语法声明一个数组:```ctype arrayName[arraySize];```其中,`type` 是数组中元素的数据类型,`arrayName` 是数组的名称,`arraySize` 是数组的大小,表示数组可以容纳的元素个数。
例如:```cint numbers[5]; // 声明一个包含5个整数的数组```2. **数组索引:** 数组中的每个元素都有一个唯一的索引,索引从0开始,递增到数组大小减1。
例如,对于上面的数组`numbers`,索引范围是0到4。
```cnumbers[0] = 10; // 给数组的第一个元素赋值numbers[1] = 20; // 给数组的第二个元素赋值```3. **数组初始化:** 在声明数组的同时,可以初始化数组的元素。
```cint numbers[5] = {10, 20, 30, 40, 50}; // 初始化一个包含5个整数的数组```4. **多维数组:** C语言支持多维数组,例如二维数组。
二维数组可以看作是一个表格,有行和列。
```cint matrix[3][3] = {{1, 2, 3},{4, 5, 6},{7, 8, 9}};```5. **数组和指针:** 数组和指针在C语言中有着紧密的关系。
数组名本身就是一个指向数组首元素的指针。
```cint arr[3] = {10, 20, 30};int *ptr = arr; // 数组名arr是指向数组首元素的指针```6. **数组作为函数参数:** 数组可以作为函数参数传递。
在函数中,数组参数通常以指针的形式传递。
```cvoid printArray(int arr[], int size) {for (int i = 0; i < size; i++) {printf("%d ", arr[i]);}printf("\n");}```这些是关于C语言中数组的基本概念。
c语言中数组的正确定义
c语言中数组的正确定义
在C语言中,数组是一种由相同类型的元素组成的数据结构。
数组的正确定义需要包括以下几个方面:
1. 数据类型,首先需要指定数组中元素的数据类型,可以是整数、浮点数、字符等,例如int、float、char等。
2. 数组名,数组名是数组的标识符,用于访问数组元素,命名时应符合命名规范,具有描述性,易于理解。
3. 元素个数,需要指定数组中元素的个数,例如可以是10、20、100等,这个个数也被称为数组的长度。
4. 定义符号,使用方括号[]来表示数组的定义,例如int
arr[10]表示定义了一个包含10个整数元素的数组arr。
综合起来,数组的正确定义可以如下所示:
c.
int arr[10];
这表示定义了一个包含10个整数元素的数组arr。
在这个定义中,int表示数组元素的数据类型,arr表示数组名,10表示数组中元素的个数。
需要注意的是,数组的下标是从0开始的,因此在访问数组元素时,要特别注意数组下标的范围,以避免发生越界访问的错误。
另外,C语言中并没有内置的数组越界检查,因此在使用数组时要格外小心,确保不会越界访问。
c语言数组的类型
c语言数组的类型
C语言数组是一种数据类型,用于存储同一类型的多个数据元素。
数组可以在声明时指定其大小,并且可以使用数字索引来访问每个元素。
C语言中有两种类型的数组:一维数组和多维数组。
一维数组是指只有一个索引的数组。
例如, int num[5]是一个包含5个整数的一维数组。
可以使用 num [0] ,num [1] ,num [2] ,num [3] 和 num [4] 来访问每个数组元素。
多维数组是指具有多个索引的数组。
例如, int twoD [3] [4]是一个包含12个整数的二维数组。
可以使用 twoD [0] [0] ,twoD [0] [1] ,twoD [0] [2] ,twoD [0] [3] ,twoD [1] [0] ,twoD [1] [1] ,twoD [1] [2] ,twoD [1] [3] ,twoD [2] [0] ,twoD [2] [1] ,twoD [2] [2] 和 twoD [2] [3] 来访问每个数组元素。
数组是一种非常有用的数据类型,可以用于存储大量数据,并且可以通过索引来访问每个数据元素。
在C语言中,数组有两种类型:一维数组和多维数组。
熟练掌握这些类型的数组可以帮助程序员更好地使用C语言来解决问题。
- 1 -。
c语言的数组的定义
c语言的数组的定义C语言是一种广泛应用的编程语言,其数组是其重要的组成部分。
在C语言中,数组是一种存储多个相同类型的数据的数据结构。
数组的定义是C语言中的基础知识之一,下面我们就来详细了解一下。
在C语言中,数组的定义需要指定数组的类型和数组的大小。
数组的类型可以是整型、浮点型、字符型等,而数组的大小是指数组中元素的个数。
数组的定义格式为:类型数组名[数组大小]。
例如,我们可以定义一个整型数组,数组名为numbers,大小为5,如下所示:int numbers[5];这样就定义了一个名为numbers的整型数组,它可以存储5个整数。
在定义数组时,C语言会为数组分配一块连续的内存空间,每个元素占用相同的字节大小。
在定义数组后,我们可以对数组进行初始化,即给数组中的元素赋初值。
数组的初始化可以在定义时完成,也可以在后续的代码中逐个赋值。
例如,我们可以定义一个整型数组并对其进行初始化,如下所示:int numbers[5] = {1, 2, 3, 4, 5};这样就定义并初始化了一个整型数组numbers,其中的元素依次为1、2、3、4、5。
除了直接赋值初始化外,我们还可以使用循环结构对数组进行初始化。
例如,我们可以使用for循环对整型数组进行赋值初始化,如下所示:int numbers[5];for (int i = 0; i < 5; i++) {numbers[i] = i + 1;}这样就通过循环对整型数组numbers进行了赋值初始化,使其元素依次为1、2、3、4、5。
数组的定义不仅可以是一维的,还可以是多维的。
多维数组是指数组中的每个元素都是一个一维数组。
例如,我们可以定义一个二维整型数组,如下所示:int matrix[3][3];这样就定义了一个名为matrix的二维整型数组,它可以存储3行3列的整数矩阵。
在定义多维数组时,需要指定每一维的大小。
在使用数组时,我们可以通过数组名和索引来访问数组中的元素。
c语言--- 数组
=10×2
数组名表示数组所 1012 在内存首地址也是 a[0]的地址,是地 1014 址常量 :
1028
80
66 :
第7章 数 组
引言
一维数组 二维数组 字符数组与字符串
7.1 引言
一、数组的引入 为了便于处理一批类型相同的数据,引入了数组类型.
例:某班有40名学生,求该班成绩的平均分
#include <stdio.h> main( ) { int j , sum , s ; float ave ; sum=0; for(j=1; j<=40 ; j++) { scanf(“%d”,&s); sum=sum+s; } ave=sum/40; printf(“ave=%f”,ave); } 假设现在要保存每个学 生的成绩,那就需要40个变 量,但这样一来输入、输出、 计算都会变得繁琐,若成千 上万数据,显然不合适。 在这种情况下,我们可以 使用数组类型,声明一个数 组含有40个整型元素,每个 数组元素存放一个成绩,这 样,成绩的输入、输出、计 算就可通过循环来实现.
• 如果要对n个数据排序,就需要进行n-1轮的比较,每次都对相 邻两个数进行比较,将较大的数交换到后一个元素中。每1轮 的比较都找出未排好的数据中的最大数放在这几个数的后面。 • 例如,第1轮需要比较n-1次,在n个数中找出最大数放在数组 的最后1个元素中;
• 第2轮将对剩下的前n-1个数进行比较,需要比较(n-1)-1次,将 前n-1个数中的最大者放入数组的倒数第2个元素中; • ……以此类推,第n-1轮需要进行1次比较,将剩下的2个数中 的较大者放入a[1]中,将最小的数放入a[0]中。 • 当第n-1轮比较进行完后,所有的数据都按照升序在数组中排 列。
C语言 数组ppt
if (a[j] < a[imin]) imin = j;
} if (imin != i) {
temp = a[i]; a[i] = a[imin]; a[imin] = temp; } }
for (i=0; i<10; i++) printf("%3d",a[i]);
第6章 数组
内容提要
数组定义和基本操作; 常用算法:求最大最小值、排序、查找等; 用字符数组存取字符串; 使用字符串处理函数处理字符串
2023/10/17
2
一维数组(Array)的定义
类型 数组名[长度]; – 长度为常量表达式,不可以是变量(但C99提供了动态数组)
例:int a[10]; – 定义一个有10个元素的数组,每个元素的类型均为int – 系统会在内存分配连续的10个int空间给此数组 – a 是数组名,同时也代表着此数组的首地址
31
int a[10]={1,3,5,7,9,12,14,16,18,20}, number; int low = 0, high= 9 ,mid,pos = -1, find = 0
printf("请输入要查找的数:"); scanf("%d",&number);
while (low <= high) {
9
20
#include <stdio.h> int main() {
Bubble sort
int a[10]={93,84,52,46,25,0,66,18,39,70}, i, j, temp;
C语言程序设计_2 第8章 数组
int a[3][3]={{1,2,3},{4,5,6},{7,8,9}} a[3][3]={{1 },{4 },{7
.2). 按行连续赋值 把数组元素顺序赋值。例如: 把数组元素顺序赋值。例如:
int a[5][3]={1,2,3,4,5,6,7,8,9} a[5][3]={1
通常写为如下矩阵形式,比较直观: 通常写为如下矩阵形式,比较直观:
二维数组存储是按行排列的, 二维数组存储是按行排列的, 即放完一行之后顺次放入第二 行。
8.2.2 二维数组元素的表示方法
二维数组的元素也称为双下标变量,其表示的形式为: 二维数组的元素也称为双下标变量,其表示的形式为:
数组名[下标1][下标 数组名[下标1][下标2] 下标2
其中下标应为整型常量或整型表达式。例如: 其中下标应为整型常量或整型表达式。例如:
8.2 二维数组
只有一个下标的数组称为一维数组, 只有一个下标的数组称为一维数组,其数组 元素称为单下标变量。 元素称为单下标变量。有多个下标的数组称为 多维数组, 其数组元素称为多下标变量。 多维数组, 其数组元素称为多下标变量。 最 常用的是二维数组, 常用的是二维数组,更高维数的数组与二维数 组相似。 组相似。
8.1.2 数组元素的表示方法
数组元素是数组的基本单元,它是一种变量,其标识方法为 数组元素是数组的基本单元, 它是一种变量, 数组名后跟一个下标。下标指定元素在数组中的顺序号。 数组名后跟一个下标。下标指定元素在数组中的顺序号。数组元 素的一般形式为: 素的一般形式为:
数组名[下标] 数组名[下标]
例如,单独使用一个下标变量: 例如,单独使用一个下标变量:
int a[10]; a[10] a[7]=6; a[7]=6
《C语言程序设计》课件 第五章 数组
a(5948)
a[2](5964) a[1](5956) a[0](5948) 图 5-10
a[2][1] (5968) a[2][0] (5964) a[1][1] (5960) a[1][0] (5956) a[0][1] (5952) a[0][0](5948)
return 0;
}
5.1.4一维数组程序举例
3.用选择法对输入的n个学生的单科成绩进行 从小到大排序。
编程思路: 直接选择排序的过程是:首先在所有数据中找出值 最小(最大)的数据,把它与第1个数据交换,然后 在其余的数据中找出值最小(最大)的数据,与第2 个数据交换......依次类推,这样,n个数据经过n-1轮 交换后可得到有序结果。
printf("%3d ",a[i]); printf("\n"); return 0; }
5.1.3 一维数组的初始化 5.1.3 一维数组的初始化
数组初始化常见的格式:
1.用大括号括起来的常量表达式列表,常量表达式 之间用逗号进行分隔: int a[10]={1,2,3,4,5,6,7,8,9,10};
注意:
不要将a[i][j]写成a[i,j],否则编译系统会将逗号分隔 符作为逗号运算符处理,即将a[i,j]视为a[j]。
5.2.2二维数组元素的引用
可以将二维数组看成是特殊的一维数组。
例如,二维数组a[3][2]可以看成是长度为3的一维数组, 所含的3个数组元素分别为:a[0]、a[1]、a[2]
for(i=0;i<3;i++) for(j=0;j<5;j++)
c语言 数组
printf("%f\n", s3);
printf("%f\n", s2); printf("%f\n", s1);
}
第六章 数 组
在定义数组时, 需要注意的是: (1) 表示数组长度的常量表达式,必须是正的整型常量表
达式。
(2) 相同类型的数组、变量可以在一个类型说明符下一起
说明,互相之间用逗号隔开。例如,int a[5], b[10], i;
例如, int a[3][2]; 表示数组a是一个3×2(3行2列)的数组, 共有6个元素, 每个元素都是int型。
第六章 数 组
二维数组的应用之一是矩阵和行列式。其中,左起第一 个下标表示行数,第二个下标表示列数。我们也可以把二维 数组看成是一种特殊的一维数组:它的元素又是一个一维数 组。 例如,可将以上的a数组看成是一个一维数组,它有3个 元素, 分别是a[0],a[1],a[2],每个元素又是一个 包含2个元素的一维数组, 如图6.2所示, 因此可以把a[0], a [1],a[2]看作是三个一维数组的名字。上面定义的二 维数组就可理解为定义了三个一维数组, 即相当于
第六章 数 组
例 6.2 用数组实现例6.1。
main()
{ int i;
float score[5]; printf("Enter five scores: ");
for (i=0; i<5; i++)
scanf("%f", &score[i]); printf("\nThe scores in reverse order are: ");
这样,数组的前几个元素的值为:
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
系统将分配一个字符指针所需的内存空间,可能只能容纳2个或4个字符。如果你在源文件中作如下定义:
char a[MAX];
但在头文件作如下说明;
extern char *a;
就会导致可怕的后果。为了避免出现这种情况,最好的办法是保证上述说明和定义的一致性,例如,如果在源文件中作如下定义:
就相当于
while(*strings !=NULL)
在写函数文档(例如在函数前面加上注释,或者写一份备忘录,或者写一份设计文档)时,写进函数是如何知道数组参数的大小是非常重要的,例如,你可以非常简略地写上"以空指针结束"或"数组elephants中有numElephants个元素"(如果你在程序中用数字13表示数组的大小,你可以写进"数组arr中有13个元素"这样的描述,然而用确切的数字表示数组的大小不是一种好的编程习惯)。
char a[MAX];
那么在相应的头文件中就作如下说明,
externchar a[];
上述说明告诉头文件a是一个数组,不是一个指针,但它并不指示数组a中有多少个元素,这样说明的类型称为不完整类型。在程序中适当地说明一些不完整类型是很常见的,也是一种很好的编程习惯。
问题的关键是:如果你将某些数据存入a[MAX]中,往往就会破坏原来紧跟在数组a后面的数据。即使查看a[MAX]的值也是应该避免的,尽管这样做一般不会引出什么问题。
为什么在C程序中有时要用到&a[MAX]呢?因为很多C程序员习惯通过指针遍历一个数组中的所有元素,即用
for(i=0;i<MAX;++i)
第二,这种方式背离了C语言的常规风格。人们已经习惯了C语言中数组下标的工作方式,如果你的程序使用了另外一种方式,别人就很难读懂你的程序,而经过一段时间以后,连你自己都可能很难读懂这个程序了。
请参见:
9.2 可以使用数组后面第一个元素的地址吗?
9.3 为什么要小心对待位于数组后面的那些元素的地址呢?
第二,数组和指针能非常和谐地在一起工作。当数组出现在一个表达式中时,它和指向数组中第一个元素的指针是等价的,因此数组和指针几乎可以互换使用。此外,使用指针要比使用数组下标快两倍(请参见9.5中的例子)。
第三,将数组作为参数传递给函数和将指向数组中第一个元素的指针传递给函数是完全·
为了告诉函数数组参数的大小,人们通常采用以下两种方法:
第一种方法是将数组和表示数组大小的值一起传递给函数,例如memcpy()函数就是这样做的:
char source[MAX],dest[MAX];
/*... */
memcpy(dest,source,MAX);
请参见:
9.3 为什么要小心对待位于数组后面的那些元素的地址呢?
9.5 通过指针或带下标的数组名都可以访问数组中的元素,哪一种方式更好呢?
9.3. 什么要小心对待位于数组后面的那些元素的地址呢?
如果你的程序是在理想的计算机上运行,即它的取址范围是从00000000到FFFFFFFF,那么你大可以放心,但是,实际情况往往不会这么简单。
等价的。将数组作为参数传递给函数时可以采用值传递和地址传递两种方式,前者需要完整地拷贝初始数组,但比较安全;后者的速度要快得多,但编写程序时要多加小心。C++和ANSIC中都有const关键字,利用它可以使地址传递方式和值传递方式一样安全。如果你想了解更多的细节,请参见2.4,8.6和第7章"指针和内存分配"开头部分的介绍。
在有些计算机上,地址是由两部分组成的,第一部分是一个指向某一块内存的起始点的指,针(即基地址),第二部分是相对于这块内存的起始点的地址偏移量。这种地址结构被称为段地址结构,子程序调用通常就是通过在栈指针上加上一个地址偏移量来实现的。采用段地址结构的最典型的例子是基于Intel 8086的计算机,所有的MS-DOS程序都在这种计算机上运行(在基于Pentium芯片的计算机上,大多数MS-DOS程序也在与8086兼容的模式下运行)。即使是性能优越的具有线性地址空间的RISC芯片,也提供了寄存器变址寻址方式,即用一个寄存器保存指向某一块内存的起始点的指针,用另一个寄存器保存地址偏移量。
数组和指针之间的这种联系会引起一些混乱,例如以下两种定义是完全相同的:
void f(chara[MAX])
{
/*... */
}
void f(char *a)
{ ·
/*... */
}
注意:MAX是一个编译时可知的值,例如用#define预处理指令定义的值。
第二种方法是引入某种规则来结束一个数组,例如在C语言中字符串总是以ASCII字符NUL('\0')结束,而一个指针数组总是以空指针结束。请看下述函数,它的参数是一个以空指
针结束的字符指针数组,这个空指针告诉该函数什么时候停止工作:
void printMany(char *strings口)
因为指针和数组几乎是相同的,因此你可以定义一个指针,使它可以象一个数组一样引用另一个数组中的所有元素,但引用时前者的下标是从1开始的:
/*don't do this!!*/
int a0[MAX],
int *a1=a0-1; /*&a0[-1)*/
现在,a0[0]和a1[1)是相同的,而a0[MAX-1]和a1[MAX]是相同的。然而,在实际编程中不应该这样做,其原因有以下两点:
{
int i;
i=0;
while(strings[i]!=NULL)
{
puts(strings[i]);
++i;
}
}
正象9.5中所说的那样,C程序员经常用指针来代替数组下标,因此大多数C程序员通常会将上述函数编写得更隐蔽一些:
(1) 程序仍能正确运行;
(2) 程序会异常终止或崩溃;
(3) 程序能继续运行,但无法得出正确的结果;
(4) 其它情况。
换句话说,你不知道程序此后会做出什么反应,这会带来很大的麻烦。有些人就是抓住这一点来批评C语言的,认为C语言只不过是一种高级的汇编语言。然而,尽管C程序出错时的表现有些可怕,但谁也不能否认一个经过仔细编写和调试的C程序运行起来是非常快的。
第9章 数 组
C语言处理数组的方式是它广受欢迎的原因之一。C语言对数组的处理是非常有效的,其原因有以下三点:
第一,除少数翻译器出于谨慎会作一些繁琐的规定外,C语言的数组下标是在一个很低的层次上处理的。但这个优点也有一个反作用,即在程序运行时你无法知道一个数组到底有多大,或者一个数组下标是否有效。ANSI/ISOC标准没有对使用越界下标的行为作出定义,因此,一个越界下标有可能导致这样几种后果:
同样,如果数组a(其元素个数为MAX)刚好存放在某段内存的尾部,那么地址&a[MAX]就是没有意义的,如果你的程序中使用了&a[MAX],而编译程序又要检查&a[MAX]是否有效,那么编译程序必然就会报告没有足够的内存来存放数组a。
尽管在编写基于Windows,UNIX或Macintosh的程序时不会遇到上述问题,但是C语言不仅仅是为这几种情况设计的,C语言必须适应各种各样的环境,例如用微处理器控制的烤面包炉,防抱死刹车系统,MS-DOS,等等。严格按C语言标准编写的程序能被顺利地编译并能服务于任何目的,但是,有时程序员也可以适度地背离C语言的标准,这要视程序员、编译程序和程序用户三者的具体要求而定。
9.2. 可以使用数组后面第一个元素的地址吗?
你可以使用数组后面第一个元素的地址,但你不可以查看该地址中的值。对大多数编译程序来说,如果你写如下语句:
int i,a[MAX],j;
那么i和j都有可能存放在数组a最后一个元素后面的地址中。为了判断跟在数组a后面的是i还是j,你可以把i或j的地址和数组a后面第一个元素的地址进行比较,即判断"&i==&a[MAX]"或"&j==&a[MAX]"是否为真。这种方法通常可行,但不能保证。
如果你的程序使用段地址结构,而在基地址处刚好存放着数组a0(即基地址指针和&a0[0]相同),这会引出什么问题呢?既然基地址无法(有效地)改变,而偏移量也不可能是负值,因此"位于a0[0]前面的元素"这种说法就没有意义了,ANSIC标准明确规定引用这个元素的行为是没有定义的,这也就是9.1中所提到的方法可能行不通的原因。
注意:a[MAX]是一个有效的地址,但该地址中的值并不是数组a的一个元素(见9。2)。
上述这种差别有时会引起混乱,因为当你说"数组中的第一个元素"时,实际上是指"数组中下标为。的元素",这里的"第一个"的意思和"最后一个"相反。
尽管你可以假造一个下标从1开始的数组,但在实际编程中不应该这样做。下文将介绍这种技巧,并说明为什么不应该这样做的原因。
请参见:
9. 1数组的下标总是从0开始吗?
9.2可以使用数组后面第一个元素的地址吗?
9.4. 在把数组作为参数传递给函数时,可以通过sizeof运算符告诉函数数组的大小吗?
不可以。当把数组作为函数的参数时,你无法在程序运行时通过数组参数本身告诉函数该数组的大小,因为函数的数组参数相当于指向该数组第一个元素的指针。这意味着把数组传递给函数的效率非常高,也意味着程序员必须通过某种机制告诉函数数吗?
是的,对数组a[MAX](MAX是一个编译时可知的值)来说,它的第一个和最后一个元素分别是a[o]和aLMAX-1)。在其它一些语言中,情况可能有所不同,例如在BASIC语言中数组a[MAX]的元素是从a[1]到a[MAX],在Pascal语言中则两种方式都可行。