赞
踩
四、数组的地址(继续前文编号)
数组是连续有序储存的同类型值,只要获得首地址(第0个成员的内存地址),其它成员的地址也就知道了,就能遍历整个数组。比如,声明一个数组:int arr[5]={1,2,3,4,5}; 又 int* p=&arr[0]; 那么指针p中保存的就是数组 arr 的首地址,故有*p值是1; ( 首个成员的值 )。C语言为简化计,规定数组名等同于数组首地址,即有 *p=arr; 。 如此,把数组名传入一个函数,就等同于传入一个指针变量。在函数内部,就可以通过这个指针变量获得整个数组。
同理,对于二维甚至多维数组,数组名也是这些数组的首地址。
五、数组指针的加减计算
仍接上面的例子,p是指向数组 arr 首地址指针,*p的值是1;接下来我们给p加上1,此时 *(p+1) 的值就是2;也就是说,首地址指针加上n则指针就指向第n个成员(注意我们讲地址还有第几个成员均从0开始计),然后用 *(p+n) 就能取出这个地址的值。指针能加也能减,减就是指针指向回退一个成员。十分注意的是指针加减后的结果不能越界。
由于指针p与数组名arr等价,所以用*(arr+n)来取第n个成员的值也是一样的。
关于数组的地址及指针加减运算我们用一个例子做说明:
- #include<stdio.h>
- void myArr(int* arr)
- {
- int* p = arr; //p指向第0号成员
- int temp = *p;
- printf("数组arr的第0号成员是:%d\n", temp);
- p = p + 4;//p指向了第4号成员
- temp = *p;
- printf("数组arr的第4号成员是:%d\n", temp);
- p = p - 2;//p从4回退2个位置指向2号成员
- temp = *p;
- printf("数组arr的第2号成员是:%d\n", temp);
- }
- int main(void)
- {
- int arr[5] = { 1,2,3,4,5 };
- myArr(arr);
- printf("-----------------------\n");
- printf("数组arr的第2号成员是:%d\n", *(arr + 2)); //用arr替代p进行计算
- getchar();
- return 0;
- }
运行结果:
数组arr的第0号成员是:1
数组arr的第4号成员是:5
数组arr的第2号成员是:3
-----------------------
数组arr的第2号成员是:3
六、数组的复制
数组名字是指针,所以复制数组名字并不是真正的复制数组,而是复制了一个指针,原指针和复制指针共同指向同一个数组,如果原数组消失则复制的数组也不存在了。
简单的复制方法是利用循环一个成员一个成员的完成复制,具体可看下面代码:
- int arr[5] = { 1,2,3,4,5 };
- int arrBak[5] = { 0 };
- for (int i = 0; i < 5; i++) arrBak[i] = arr[i]; //逐个成员复制
- for (int i = 0; i < 5; i++) printf("%d ", arrBak[i]); //显示复制结果
运行结果:1 2 3 4 5(复制完成)
对于二维或者多维数组,复制需要开双重循环或多重循环。
还有一种赋值方法,就是调用memcpy() 函数直接把数组所在的那一段内存再复制出一份。memcpy()有3个参数:
参1 目标数组名 参2 源数组名 参3 目标数组字节长度。见下例:
- int arr[5] = { 1,2,3,4,5 };
- int arrBak[5];
- memcpy(arrBak, arr,sizeof(arrBak)); //完成复制
- for (int i = 0; i < 5; i++) printf("%d ", arrBak[i]); //显示复制结果
运行结果:1 2 3 4 5(结果与循环方法相同,函数方法速度快于循环方法)
说明:由于版本不同,memcpy是否包含在<stdio.h>不能确定,如报错请包含<string.h>。
七、数组作为函数的参数
1. 数组作为函数的参数,一般会同时传入数组名和数组成员数。由于数组名是一个指针,如果只传数组名,那么函数
只知道数组开始的地址,不知道有几个成员。如果函数的参数是多维数组,那么除了第一维的成员数可以当作参数传入函数,
其他维的成员数需要写入函数参数声明。()
2.数组字面量作为函数参数,直接将数组字面量传入函数。方法是带有大括号的数组各成员的值直接放到参数名的位置,后边再跟上数组成员数这个参数;然后在大括号前面一对小括号,括号里是函数数组参数声明(但把数组名去掉)。这种方式类似于用数组类型对传入的字面量(数组成员值)进行强转,让编译器明白这组值的类型。
以上两项,特别是第2项用语言表达不是很明白,还是放到下面的例子中进一步说明,代码如下:
- #include<stdio.h>
- int mySum(int a[][5], int n)
- {
- int sum = 0;
- for (int i = 0; i < n; i++)
- {
- for (int j = 0; j < 5; j++)
- {
- sum += a[i][j];
- }
- }
- return sum;
- }
- int main(void)
- {
- int arr[2][5] = { {1, 2, 3, 4, 5},{6, 7, 8, 9, 10} };
- int sum=mySum(arr, 2); //传入数组名及第一维成员数
- printf("%d\n", sum); //运算结果:55
- sum = mySum((int[][5]) { {1, 2, 3, 4, 5}, { 6, 7, 8, 9, 10 } }, 2);
- //将数组字面量直接及第一维成员数直接传入函数,注意(int[][5])中无数组名,只剩类型
- printf("%d\n", sum);//运算结果:55
- getchar();
- return 0;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。