数组名作函数参数
- 用数组名作函数参数时,因为实参数组名代表该数组首元素的地址,形参应该是一个指针变量。
- C编译都是将形参数组名作为变量来处理的。
- 实参数组名是指针常量,但形参数组名是按指针变量处理。
- 在函数调用进行虚实结合后,它的值就是实参数组首元素的地址。
- 在函数执行期间,形参数组可以再被赋值。
例如:
void fun (arr[],int n){ printf("%d\n", *arr); // 输出 a[0]的值 arr=arr+2; printf("%d\n", *arr); // 输出 a[2]的值 }
- 例子
将数组a中n个整数按相反顺序存放
#include <stdio.h>
void main() {
void inv(int x[], int n);
int i,a[10] = {1,2,3,4,5,6,7,8,9,10};
int *p;
for (i = 0; i < 10; i++) {
printf("%d ", a[i]);
}
printf("\n");
inv(a, 10);
for (i = 0; i < 10; i++) {
printf("%d ", a[i]);
}
printf("\n");
}
void inv(int x[], int n) {
int temp, i, j, m = (n - 1) / 2;
for (i = 0; i <= m; i++) {
j = n - 1 - i;
temp = x[i];
x[i] = x[j];
x[j] = temp;
}
}
用指针变量作实参
#include <stdio.h>
void main() {
void inv(int *x, int n);
int i,arr[10] = { 1,2,3,4,5,6,7,8,9,10 }, *p;
p = arr; // 如果用指针变量作实参,必须先使指针变量有确定的值,指向一个已定义的单元。
for (i = 0; i < 10; i++) {
printf("%d ", arr[i]);
}
printf("\n");
inv(p, 10);
for (p = arr; p <arr + 10; p++) {
printf("%d ",*p);
}
printf("\n");
}
void inv(int *x, int n) {
int temp, *p,*i, *j, m = (n - 1) / 2;
p = x + m;
i = x;
j = x + n - 1;
for (; i <= p; i++,j--) {
temp = *i;
*i = *j;
*j = temp;
}
}
用指针方法对10个整数按由大到小顺序排序。
#include <stdio.h>
void main(){
void sort(int *x, int n);
int i, *p, a[10] = {9,8,6,2,3,4,5,1,2,10};
p = a;
for (i = 0; i < 10; i++) {
printf("%d ", a[i]);
}
printf("\n");
sort(p, 10);
for (i = 0; i < 10; i++) {
printf("%d ",*p);
p++;
}
printf("\n");
}
void sort(int *x, int n) {
int i, j, k, t;
for (i = 0; i < n - 1; i++) {
k = i;
for (j = i + 1; j < n; j++) {
if (*(x+j)>*(x+k)) {
k = j;
}
if (k != i) {
t = *(x + i);
*(x + i) = *(x + k);
*(x + k) = t;
}
}
}
}
2、多维数组与指针
- 二维数组在内存中存储时,将二维转换为一维形式。
- C语言中定义的二维数组可以看作是一个一维数组,而这个一维数组的每个元素又是一个一维数组。
- 从二维数组的角度来看,a是二维数组名,a代表整个二维数组的首地址,也是二维数组0行的首地址,等于1000。
a+1 代表第一行的首地址,等于1008。a+i 第i行首地址为:a+i×4×2
。 - 数组名可以代表数组首地址,所以 a[0] 代表0行0列地址,即 &a0 。
a[1] 的值是 &a1 ,a[2] 的值是 &a2 。 - a, a[0], a[1],a[2]本身不占内存,不存放数据,仅表示一个地址。
行元素地址表示:
a+0
、a+1
、a+2
等等;
列元素地址表示:a[0]+0
、a[0]+1
、a[0]+2
、a[0]+3
等等- 元素值:
*(a[i]+j)
<=>*(*(a+i)+j)
<=>a[]i[j]
- 元素值:
a[i]
<=> *(a+i)
等价:第i行第0列的元素地址 &a[i][0]
a[i]+j
<=> *(a+i)+j
等价:第i行第j列的元素地址 &a[i][j]
a[1]+3
<=> *(a+1)+3
等价:第1行第3列的元素地址 &a[1][3]
行指针与列指针
a+i
=&a[i]
=a[i]
=*(a+i)
=&a[i][0]
,值相等,含义不同。a+i
<=>&a[i]
,表示第i行首地址,指向行a[i]
<=>*(a+i)
<=>&a[0][0]
,表示第i行第0列元素地址,指向列
- 例子
使用指针的方式输出二维数组元素的值。
#include <stdio.h>
void main() {
float f[3][4] = { {0.0, 0.1, 0.2, 0.3},{1.0, 1.1, 1.2, 1.3},{2.0, 2.1 ,2.2, 2.3} };
float *pf;
int i;
pf = f[0];
for (i = 0; i < 12; i++) {
if (i != 0 && i % 4 == 0){
printf("\n");
}
printf("%6.2f", *pf++);
}
printf("\n");
}
- 表达式
*pf++
等价于*(pf++)
,其含义是取*pf
的值作为表达式的值,再使pf加1
。通过pf值的变化,逐一访问 f数组 中每个元素。 - 顺序输出数组元素方法简单,而指定输出数组元素则要进行地址的计算。
例如二维数组为n X m (n为行,m为列)首元素地:址为a[0]
a[i][j]
在数组中相对位置的计算公式:
i * m + j
(m为每行元素个数)
a0 | a0 | a0 | a0 |
a1 | a1 | a1 | a1 |
a2 | a2 | a2 | a2 |
位移量的计算:
a[1][1] = 1*4+1 = 5
a[2][3] = 2*4+3 = 11
若初值:p=a[0]
- 则:
*(p+1*4+1) = *(p+5) = a[1][1]
*(p+2*4+3) = *(p+11) = a[2][3]
- 数组下标从0开始便于计算相对位置
- 则:
多维数组的指针变量
二维数组指针变量说明
- 一般形式为:
类型说明符
(*指针变量名)[长度]
- 例如:
int(*p)[4]
- 把二维数组a分解为一维数组a[0],a[1],a[2]之后,
设p为指向二维数组的指针变量。 - 例子
使用指向一维数组的指针变量输出二维数组元素的值。
#include <stdio.h>
void main() {
float f[3][4] = { {0.0, 0.1, 0.2, 0.3},{1.0, 1.1, 1.2, 1.3},{2.0, 2.1 ,2.2, 2.3} };
float (*pf)[4];
int i,j;
pf = f;
for (i = 0; i < 3; i++) {
for (j = 0; j < 4; j++) {
printf("%6.2f", *(*pf+i)+j);
}
printf("\n");
}
}
多维数组指针作为函数参数
- 一维数组名可以作为函数参数传递,多维数组名也可以作为函数参数传递。
- 例子
3个学生各学4门课,计算总平均分,输出第n个学生成绩
#include <stdio.h>
void main() {
void average(float *p, int n);
void search(float(*p)[4], int n);
float score[3][4] = { {65, 67, 79, 60}, { 80,87,90,81 }, { 90,99,100,98 } };
average(*score, 12);
search(score, 1);
}
void average(float *p, int n) {
float *p_end, sum = 0, aver;
p_end = p + n - 1;
for (; p <= p_end; p ++) {
sum = sum + (*p);
}
aver = sum / n;
printf("平均成绩:%6.2f\n", aver);
}
void search(float(*p)[4], int n) {
int i;
printf("第%d学生的成绩:\n", n);
for (i = 0; i < 4; i++) {
printf("%6.2f ", *(*(p + n) + i));
}
printf("\n");
}
评论