四维数组,可用于航天卫星,三维+时间
1 #define _CRT_SECURE_NO_WARNINGS 2 3 #include<stdio.h> 4 #include<stdlib.h> 5 6 main() 7 { 8 int a[2][3][4][5]; 9 int i, j, k, l; 10 int num = 0; 11 int *p; 12 int find = 116; 13 14 printf("%d ", sizeof(a)); 15 printf("%d ", sizeof(a) / sizeof(int)); 16 17 for (p = &a[0][0][0][0];p < &a[0][0][0][0] + 120;p++) 18 { 19 *p = num; 20 num++; 21 } 22 23 for (i = 0;i < 2;i++) 24 { 25 for (j = 0;j < 3;j++) 26 { 27 for (k = 0;k < 4;k++) 28 { 29 for (l = 0;l < 5;l++) 30 { 31 printf("%7d", *(*(*(*(a + i) + j) + k) + l)); 32 } 33 printf(" "); 34 } 35 printf(" "); 36 } 37 printf(" "); 38 } 39 40 system("pause"); 41 }
//数组作为函数的参数,二维数组用指向一维数组的指针变量
1 #define _CRT_SECURE_NO_WARNINGS 2 3 #include<stdio.h> 4 #include<stdlib.h> 5 6 //数组作为函数的参数,二维数组用指向一维数组的指针变量 7 void showb12(int(*p)[4]) 8 { 9 int i, j; 10 11 for (i = 0;i < 3;i++) 12 { 13 for (j = 0;j < 4;j++) 14 { 15 printf("%6d", p[i][j]); 16 } 17 printf(" "); 18 } 19 } 20 21 main() 22 { 23 int b[3][4] = { {1,2,3,4},{5,6,7,8},{9,10,11,12} }; 24 25 showb12(b); 26 27 system("pause"); 28 }
行指针
//p[i][j]等价于 *(*(p + i) + j)
1 #define _CRT_SECURE_NO_WARNINGS 2 3 #include<stdio.h> 4 #include<stdlib.h> 5 #include<time.h> 6 7 main() 8 { 9 int a[3][4] = { 0,1,2,3,4,5,6,7,8,9,10,11 }; 10 11 int(*p)[4] = a;//二维数组的指针就是一个指向一维数组的指针,元素是确定的 12 13 int i, j; 14 15 scanf("%d %d", &i, &j); 16 17 printf("%d,%d,%d,%d", i, j, p[i][j], *(*(p + i) + j)); 18 //p[i][j]等价于 *(*(p + i) + j) 19 20 system("pause"); 21 }
//a[i][j]等价于*(a[i]+j)等价于*(*(a+i)+j)
//&a[i][j]等价于*(a+i)+j
1 #define _CRT_SECURE_NO_WARNINGS 2 3 #include<stdio.h> 4 #include<stdlib.h> 5 6 main() 7 { 8 int a[3][4] = { 1,2,3,4,5,6,7,8,9,10,11,12 }; 9 int i, j; 10 11 for (i = 0;i < 3;i++) 12 { 13 for (j = 0;j < 4;j++) 14 { 15 printf("%3d,%x", a[i][j], &a[i][j]); 16 } 17 printf(" "); 18 } 19 20 printf("%x,%x,%x ", a, a + 1, a + 2);//三者完全等价,a是一个行指针,代表某一行的首地址 21 printf("%x,%x,%x ", *a, *(a + 1), *(a + 2));//三者完全等价,a是一个行指针,代表某一行的首地址 22 printf("%x,%x,%x ", a[0], a[1], a[2]);//三者完全等价,a是一个行指针,代表某一行的首地址 23 printf("%d,%x ", a[1][2], &a[1][2]); 24 //a[i][j]等价于*(a[i]+j)等价于*(*(a+i)+j) 25 //&a[i][j]等价于*(a+i)+j 26 27 system("pause"); 28 }
//a是一个行指针,指向一个有4个元素的数组,4*4=16 行指针
//&a是一个指向二维数组的指针,二维数组有12个元素,4*12=48,整个二维数组
//*a是一个指向int类型数据的指针,列指针
1 #define _CRT_SECURE_NO_WARNINGS 2 3 #include<stdio.h> 4 #include<stdlib.h> 5 6 main() 7 { 8 int a[3][4] = { 1,2,3,4,5,6,7,8,9,10,11,12 }; 9 10 printf("%x,%x,%x ", a, &a, *a); 11 printf("%d,%d,%d", sizeof(*a), sizeof(*&a), sizeof(**a)); 12 //*a是一个行指针,指向一个有4个元素的数组,4*4=16 13 //*&a是一个指向二维数组的指针,二维数组有12个元素,4*12=48 14 //**a是一个指向int类型数据的指针 15 16 system("pause"); 17 }
//两者地址一样,有何不同?
1 #define _CRT_SECURE_NO_WARNINGS 2 3 #include<stdio.h> 4 #include<stdlib.h> 5 6 main() 7 { 8 int a[5] = { 1,2,3,4,5 }; 9 10 printf("%x,%x ", a, &a);//两者地址一样,有何不同? 11 12 printf("%d,%d", sizeof(*a), sizeof(*(&a))); 13 //4 20 14 15 system("pause"); 16 }
int *p = a;//指向元素的指针
int(*pa)[5] = &a;//指向数组的指针
1 #define _CRT_SECURE_NO_WARNINGS 2 3 #include<stdio.h> 4 #include<stdlib.h> 5 #include<time.h> 6 7 main() 8 { 9 int a[5] = { 1,2,3,4,5 }; 10 11 int *p = a;//指向元素的指针 12 int(*pa)[5] = &a;//指向数组的指针 13 14 printf("%d,%d ", sizeof(*p), sizeof(*pa)); 15 16 system("pause"); 17 }
输出结果:
4,20
请按任意键继续. . .
创建一个10个元素的数组,并为其随机赋值。找出最大值。用传统方法,和指针方法。
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<time.h> main() { time_t ts; srand((unsigned int)time(&ts)); int num[10]; int i; int max = 0;//保存最大数 for (i = 0;i < 10;i++) { num[i] = rand() % 100; printf("%d,%x ", num[i], &num[i]); } for (i = 1;i < 10;i++)//传统方法 { if (num[i] > num[max]) { max = i; } } printf("%d,%d ", max, num[max]); for (i = 1;i < 10;i++)//指针方法 { if (*(num + i) > num[max]) { max = i; } } printf("%d,%d ", max, num[max]); system("pause"); }
用带下标的指针变量引用一维数组元素
4种方法:
1 #define _CRT_SECURE_NO_WARNINGS 2 3 #include<stdio.h> 4 #include<stdlib.h> 5 6 main() 7 { 8 int num[10] = { 1,2,3,4,5,6,7,8,9,10 }; 9 int i; 10 int *p = num; 11 //p是变量,num是常量 12 for (i = 0;i < 10;i++) 13 { 14 printf("%d,%x", num[i], &num[i]); 15 printf("%3d,%x", *(num + i), num + i); 16 printf("%3d,%x", p[i], &p[i]); 17 printf("%3d,%x ", *(p + i), p + i); 18 } 19 20 system("pause"); 21 }
printf("%d", (p1 - p2));//-2数组至今可以判断哪个编号在前,哪个编号在后
//并且可以判断两个指针之间相隔多少个元素
//指针相减,可以判断下标,p1<p2,p1对应元素的下标小于p2对应元素的下标
1 #define _CRT_SECURE_NO_WARNINGS 2 3 #include<stdio.h> 4 #include<stdlib.h> 5 6 main() 7 { 8 int a[10] = { 1,2,3,4,5,6,7,8,9,10 }; 9 10 int *p1 = &a[3]; 11 int *p2 = &a[5]; 12 13 printf("%d", (p1 - p2));//-2数组至今可以判断哪个编号在前,哪个编号在后 14 //并且可以判断两个指针之间相隔多少个元素 15 //指针相减,可以判断下标,p1<p2,p1对应元素的下标小于p2对应元素的下标 16 system("pause"); 17 }
指针比较,在数组才有意义。
1 #define _CRT_SECURE_NO_WARNINGS 2 3 #include<stdio.h> 4 #include<stdlib.h> 5 6 main() 7 { 8 int a[5] = { 1,2,3,4,5 }; 9 printf("%x ", a); 10 int *p1 = &a[1]; 11 int *p2 = &a[2]; 12 13 if (p1 < p2) 14 { 15 printf("p1在数组内部排列比较靠前"); 16 } 17 else 18 { 19 printf("p2在数组内部排列比较靠前"); 20 } 21 22 system("pause"); 23 }
指针的加减法在非数组内部没有任何意义,而且很容易越界报错。
一个exe不能读写其他exe进程的内存
p = p + 2;//指针+2,在数组内部等价于向后移动2个元素的大小
p = p - 3;//指针-3,在数组内部等价于向前移动3个元素的大小
1 #define _CRT_SECURE_NO_WARNINGS 2 3 #include<stdio.h> 4 #include<stdlib.h> 5 6 main() 7 { 8 int a[5] = { 1,2,3,4,5 }; 9 int *p = &a[2]; 10 11 printf("%d ", a[2]); 12 13 p = p + 2;//指针+2,在数组内部等价于向后移动2个元素的大小 14 15 printf("%d ", *p); 16 17 p = p - 3;//指针-3,在数组内部等价于向前移动3个元素的大小 18 19 printf("%d ", *p); 20 21 system("pause"); 22 }
指针++,指针--
1 #define _CRT_SECURE_NO_WARNINGS 2 3 #include<stdio.h> 4 #include<stdlib.h> 5 6 main() 7 { 8 int a[5]; 9 int i = 0; 10 int *p; 11 12 printf("%x ", a); 13 14 //从头到尾扫描数组 15 for (p = a;p < a + 5;p++)//指针++,就是指针每次向前移动sizeof(指针类型)个字节 16 { 17 *p = i;//对指针指向的内容进行赋值 18 i++; 19 } 20 21 //从尾到头扫描数组 22 for (p = a + 4;p >= a;p--)//指针++,就是指针每次向前移动sizeof(指针类型)个字节 23 { 24 printf("%x ", p); 25 *p = i;//对指针指向的内容进行赋值 26 i++; 27 } 28 29 system("pause"); 30 }
通过数组的首地址引用数组元素
1 #define _CRT_SECURE_NO_WARNINGS 2 3 #include<stdio.h> 4 #include<stdlib.h> 5 6 main() 7 { 8 int a[10] = { 1,2,3,4,5,6,7,8,9,10 }; 9 10 printf("%x ", a); 11 12 printf("%d ", *(a + 4));//两者等价 13 printf("%d ", a[4]);//两者等价 14 15 system("pause"); 16 }
*p = *p - 1;//取指针变量p所指存储单元中的值,减1后再放入p所指的存储单元中,即使得值减1
1 #define _CRT_SECURE_NO_WARNINGS 2 3 #include<stdio.h> 4 #include<stdlib.h> 5 6 main() 7 { 8 int a[10] = { 1,2,3,4,5,6,7,8,9,10 }; 9 int i; 10 int *p; 11 12 printf("%x ", a);//a被编译器解析为数组的首地址 13 14 for (i = 0;i < 10;i++)//下标循环,通过下标方式访问数组 15 { 16 printf("%d,%d ", a[i], *(a + i));//a[i], *(a + i)两者等价 17 printf("%x,%x ", &a[i], a + i);//&a[i], a + i两者等价 18 } 19 20 for (p = a;p < a + 10;p++)//指针循环,通过指针方式访问数组 21 { 22 *p = *p - 1;//取指针变量p所指存储单元中的值,减1后再放入p所指的存储单元中,即使得值减1 23 printf("%d,%x ", *p, p); 24 } 25 26 system("pause"); 27 }
数组当作参数的时候,传递的是指针
1 #define _CRT_SECURE_NO_WARNINGS 2 3 #include<stdio.h> 4 #include<stdlib.h> 5 6 void fun(int a[10])//数组当作参数的时候,传递的是指针 7 { 8 printf("%d ", sizeof(a));//4 9 } 10 11 main() 12 { 13 int a[10] = { 1,2,3,4,5,6,7,8,9,10 }; 14 15 printf("%d ", sizeof(a));//40 16 17 fun(a); 18 19 system("pause"); 20 }
创建一个动态二维数组,连续内存
1 #define _CRT_SECURE_NO_WARNINGS 2 3 #include<stdio.h> 4 #include<stdlib.h> 5 #include<time.h> 6 7 main() 8 { 9 int x, y; 10 11 scanf("%d %d", &x, &y); 12 13 void *p = malloc(sizeof(int)*x*y);//分配内存,连续的内存 14 //y必须是一个已知的常量,才能将这片内存当作一个二维数组来实现 15 //连续内存,缺点:列必须是常量指定的 16 17 int(*px)[9] = p; 18 int i, j; 19 int num = 0; 20 21 for (i = 0;i < x;i++) 22 { 23 for (j = 0;j < 9;j++) 24 { 25 px[i][j] = num; 26 num++; 27 printf("%4d", px[i][j]); 28 } 29 printf(" "); 30 } 31 32 system("pause"); 33 }
创建一个动态二维数组,不连续内存
1 #define _CRT_SECURE_NO_WARNINGS 2 3 #include<stdio.h> 4 #include<stdlib.h> 5 6 main() 7 { 8 int x, y; 9 10 scanf("%d %d", &x, &y); 11 12 //二级指针可以存储指针数组的地址 13 //动态分配一片内存,存放指针数组,每一个元素都是一个地址 14 //然后将指针数组的首地址传递给pp保存 15 int **pp = malloc(sizeof(int *)*x); 16 int i, j; 17 int num = 0; 18 19 for (i = 0;i < x;i++) 20 { 21 pp[i] = malloc(sizeof(int)*y); 22 } 23 24 for (i = 0;i < x;i++) 25 { 26 for (j = 0;j < y;j++) 27 { 28 pp[i][j] = num;//等价于*(*(pp+i)+j) 29 num++; 30 printf("%4d", pp[i][j]); 31 } 32 printf(" "); 33 } 34 35 //释放内存 36 37 for (i = 0;i < x;i++) 38 { 39 free(pp[i]); 40 } 41 free(pp); 42 43 system("pause"); 44 }
二维数组,一个指针指向类型的大小,恰好要是一个一维数组的大小;二维数组是一个一维数组,每一个元素都是一个一维数组。
1 #define _CRT_SECURE_NO_WARNINGS 2 3 #include<stdio.h> 4 #include<stdlib.h> 5 #include<time.h> 6 7 main() 8 { 9 int a[3][4] = { 1,2,3,4,5,6,7,8,9,10,11,12 }; 10 int i, j; 11 int(*p)[4] = a;//创建一个指针存储二维数组的首地址,一个指向有4个元素的一维数组的指针 12 13 for (i = 0;i < 3;i++) 14 { 15 for (j = 0;j < 4;j++) 16 { 17 printf("%5d", a[i][j]); 18 } 19 printf(" "); 20 } 21 22 for (int *p = &a[0][0];p < &a[0][0] + 12;p++) 23 { 24 printf("%d,%p ", *p, p); 25 } 26 27 system("pause"); 28 }
求出数组元素的个数:
1 #define _CRT_SECURE_NO_WARNINGS 2 3 #include<stdio.h> 4 5 main() 6 { 7 int a[5] = { 1,2,3,4,5 }; 8 9 printf("%x ", a); 10 11 printf("%d", sizeof(a) / sizeof(int)); 12 13 system("pause"); 14 }
数组
为什么需要数组?
为了解决大量同类型数据的存储和使用问题
为了模拟现实世界
怎样定义一维数组?
为n个变量连续分配存储空间
所有的变量数据类型必须相同
所有变量所占的字节大小必须相等
指针变量的运算:
指针变量不能相加,不能相乘,也不能相除。
如果两个指针变量指向的是同一块连续空间中的不同存储单元,则这两个指针变量才可以相减。(即:在同一数组中相减,求出两个指针指向的单元相隔的单元数)
1 #include<stdio.h> 2 main() 3 { 4 int a[5]; 5 int * p = &a[1]; 6 int * q = &a[4]; 7 8 printf("p和q所指向的单元相隔%d个单元 ", q - p); 9 }
一堆数组的初始化
1 #include <stdio.h> 2 main() 3 { 4 int a[5] = { 1,2,3,4,5 }; /*完全初始化*/ 5 6 int a[5] = { 1,2,3 }; /*不完全初始化,未被初始化的元素自动为零*/ 7 8 int a[5]; /*不初始化,所有元素是垃圾值*/ 9 10 int a[5] = { 0 }; /*清零*/ 11 12 /*错误写法*/ 13 int a[5]; 14 a[5] = { 1,2,3,4,5 }; /*错误,只有在定义数组的同时才可以整体赋值,其他情况下整体赋值都是错误的*/ 15 16 int a[5] = { 1,2,3,4,5 }; 17 a[5] = 100; /*错误,因为没有a[5]这个元素,最大是a[4]*/ 18 19 /*如果要把a数组中的值全部复制给b数组*/ 20 int a[5] = { 1,2,3,4,5 }; 21 int b[5]; 22 b = a; /*错误的写法*/ 23 24 for (i = 0;i < 5;++i) 25 b[i] = a[i]; /*正确的写法*/ 26 }
1 #include <stdio.h> 2 main() 3 { 4 int a[5]; 5 //int b[5]; 6 7 //a = b; /* ERROR a是常量 */ 8 9 printf("%#X ", &a[0]); 10 printf("%#X ", a); 11 }
输出结果:
0XDEF9B4
0XDEF9B4
请按任意键继续. . .
1 #include <stdio.h> 2 3 void f(int * a, int len) 4 { 5 int i; 6 7 for (i = 0;i < len;++i) 8 { 9 printf("%d ", *(a + i)); /* 两者输出都一样 */ 10 } 11 printf(" "); 12 13 for (i = 0;i < len;++i) 14 { 15 printf("%d ", a[i]); /* 两者输出都一样 */ 16 } 17 printf(" "); 18 } 19 20 main() 21 { 22 int a[5] = { 1,2,3,4,5 }; 23 24 f(a, 5); /* 因为a是存放地址,所以a是int * */ 25 }
例9.1 编写程序,定义一个含有30个元素的 int 类型数组。依次给数组元素赋奇数1、3、5、...,然后按每行10个数顺序输出,最后再按每行10行个数逆序输出。
1 #include <stdio.h> 2 #define M 30 3 main() 4 { 5 int s[M], i, k = 1; 6 for (i = 0;i < M;i++) /* 给s数组元素依次赋1、3、... */ 7 { 8 s[i] = k; 9 k += 2; 10 } 11 12 printf(" Sequence Output: "); /* 按从前到后的顺序输出 */ 13 14 for (i = 0;i < M;i++) 15 { 16 printf("%4d", s[i]); 17 if ((i + 1) % 10 == 0) 18 printf(" "); /* 利用i控制换行符的输出 */ 19 } 20 21 printf(" Invert Output: "); /* 按从后到前的顺序输出 */ 22 23 for (i = M - 1;i >= 0;i--) /* 下标值从大到小 */ 24 { 25 printf("%4d", s[i]); 26 if (i % 10 == 0) 27 printf(" "); /* 利用i控制换行符的输出 */ 28 } 29 }
例9.2 编写程序,通过一个函数给主函数中定义的数组输入若干大于或等于0的整数,用负数作为输入结束标志;调用另一个函数输出该数组中的数据。
1 #include <stdio.h> 2 #define M 100 3 void arrout(int *, int); /* 函数说明语句,此函数用以输出数组中的值 */ 4 int arrin(int *); /* 函数说明语句,此函数用以给数组输入数据 */ 5 main() 6 { 7 int s[M], k; 8 k = arrin(s); /* k得到输入数据的个数 */ 9 arrout(s, k); 10 } 11 12 int arrin(int * a) 13 { 14 int i, x; 15 i = 0; 16 scanf("%d", &x); 17 while (x >= 0) 18 { 19 *(a + i) = x; 20 i++; 21 scanf("%d", &x); 22 } 23 return i; 24 } 25 26 void arrout(int * a, int n) 27 { 28 int i; 29 for (i = 0;i < n;i++) 30 { 31 printf(((i + 1) % 5 == 0) ? "%4d " : "%4d", *(a + i)); 32 } 33 /* 根据i的值来确定使用不同的格式串 */ 34 printf(" "); 35 }
例9.3 编写函数,对具有10个元素的char类型数组,从下标为4的元素开始,全部设置星号 “ * ” ,保持前4个元素中的内容不变。
1 #include <stdio.h> 2 #define M 10 3 #define B 4 4 void setstar(char *, int); 5 void arrout(char *, int); 6 main() 7 { 8 char c[M] = { 'A','B','C','D','E','F','G','H','I','J' }; 9 setstar(&c[4], M - B); 10 arrout(c, M); 11 } 12 13 void setstar(char * a, int n) 14 { 15 int i; 16 for (i = 0;i < n;i++) 17 { 18 *(a + i) = '*'; 19 } 20 } 21 22 void arrout(char * a, int n) 23 { 24 int i; 25 for (i = 0;i < n;i++) 26 { 27 printf("%c", a[i]); 28 } 29 printf(" "); 30 }
例9.4 编写程序,定义一个含有15个元素的数组,并编写函数分别完成以下操作:
(1)调用C库函数中的随机函数给所有元素赋以0~49的随机数;
(2)输出数组元素中的值;
(3)按顺序对每隔三个数求一个和数,并传回主函数;
(4)最后输出所有求出的和值。
1 #include <stdio.h> 2 #include "stdlib.h" 3 #define SIZE 15 4 #define N 3 5 void getrand(int *, int); /* 三个函数说明语句 */ 6 void getave(int *, int *, int); 7 void priarr(int *, int); 8 main() 9 { 10 int x[SIZE], w[SIZE / N] = { 0 }; /* w数组中置初值0,准备存放5个和值 */ 11 getrand(x, SIZE); /* 产生15个随机数放入x数组中 */ 12 printf("Output %d random numbers: ", SIZE); 13 priarr(x, SIZE); /* 输出15个随机数 */ 14 getave(x, w, SIZE); /* 每3个数求一个和数放入w数组 */ 15 printf("Output 5 sum numbers: "); 16 priarr(w, SIZE / N); /* 输出5个和数 */ 17 } 18 19 void getrand(int * a, int n) 20 { 21 int i; 22 for (i = 0;i < n;i++) 23 { 24 a[i] = rand() % 50; 25 } 26 } 27 28 void getave(int * a, int * b, int n) 29 { 30 int i, j, sum; 31 for (sum = 0, i = 0, j = 0;i <= n;i++) 32 { 33 sum += a[i]; /* 累加数组元素 */ 34 if ((i + 1) % 3 == 0) /* 每累加3个数进行一次处理 */ 35 { 36 b[j] = sum; /* 和值放入w数组中 */ 37 sum = 0; /* 置0,准备重新累加 */ 38 j++; /* 下标增1 */ 39 } 40 } 41 } 42 43 void priarr(int * a, int n) 44 { 45 int i; 46 for (i = 0;i < n;i++) 47 { 48 printf("%5d", a[i]); 49 if ((i + 1) % 5 == 0) 50 printf(" "); 51 } 52 printf(" "); 53 }
例9.5 将数组中的数按颠倒的顺序重新存放。在操作时,只能借助一个临时存储单元而不得另外开辟数组。
1 #include <stdio.h> 2 #define NUM 8 3 void invert(int *, int); /* 函数说明语句 */ 4 void priout(int *, int); /* 函数说明语句 */ 5 main() 6 { 7 /* 用置初值的方法给a数组放入数据 */ 8 int a[NUM] = { 10,20,30,40,50,60,70,80 }; 9 printf("Output primary data:"); /* 输出原始数据 */ 10 priout(a, NUM); 11 invert(a, NUM); 12 printf("Output the inverse data:"); /* 输出颠倒后的数据 */ 13 priout(a, NUM); 14 } 15 16 void priout(int s[], int n) 17 { 18 int i; 19 for (i = 0;i < n;i++) 20 { 21 printf("%4d", s[i]); 22 } 23 printf(" "); 24 } 25 26 void invert(int * a, int n) 27 { 28 int i, j, t; 29 i = 0; 30 j = n - 1; /* i是最前元素的下标,j是最后元素的下标 */ 31 while (i < j) /* 当i大于或等于j时,对调完成 */ 32 { 33 t = a[i]; 34 a[i] = a[j]; 35 a[j] = t; /* 下标为i和j的两个元素中的值对调 */ 36 i++; 37 j--; /* i向后移一个位置,j向前移一个位置 */ 38 } 39 }
例9.6 已知整型数组中的值在0至9的范围内,统计每个整数的个数。
以下程序中,函数 getdata 调用随机函数产生50个值在0至9的整数;函数 stat 统计每个整数的个数,并传回主函数;函数 outdata 输出结果。
1 #include <stdio.h> 2 #include <stdlib.h> 3 #define M 50 4 #define N 10 5 6 void getdata(int * s) 7 { 8 int i; 9 for (i = 0;i < M;i++) 10 { 11 s[i] = rand() % 10; 12 if (i % 10 == 0) 13 { 14 printf(" "); /* 每生成10个随机数,换行 */ 15 } 16 printf("%d ", s[i]); /* 把随机数打印出来 */ 17 } 18 } 19 20 void stat(int * a, int * c) 21 { 22 int i; 23 for (i = 0;i < N;i++) 24 { 25 c[i] = 0; /* c数组元素置初值0 */ 26 } 27 for (i = 0;i < M;i++) 28 { 29 c[a[i]]++; /* 用c数组的元素对各整数进行统计 */ 30 } 31 } 32 33 void outdata(int * c) 34 { 35 int i; 36 for (i = 0;i < N;i++) 37 { 38 printf("%d:%d ", i, c[i]); 39 } 40 } 41 42 main() 43 { 44 int a[M], c[N]; 45 getdata(a); 46 stat(a, c); 47 printf(" Output the result: "); 48 outdata(c); 49 }
例9.7 已知存放在 a 数组中的数不相重,在 a 数组中查找和 x 值相同的元素的位置。若找到,输出该值和该值在 a 数组中的位置;若没找到,输出相应的信息。
以下程序中,arrin 函数用于输入数据。函数首先要求输入一个整数,以确定将给数组输入数据的个数,然后给数组输入数据。
在主函数中输入带查找的数据。
函数 search 用以查找 x 在数组中的位置,位置值传送给变量 p。若 p 的值为 -1,表示在数组中没有值为 x 的元素,否则 p 中的值即为所找的位置。
1 #include <stdio.h> 2 #define NUM 30 3 4 int arrin(int * a) 5 { 6 int i, n; 7 do /* 当指定数组元素个数超出范围时,重新输入 */ 8 { 9 printf("Enter number of elements,0<=n<%d:", NUM); 10 scanf("%d", &n); 11 } while ((n < 1) || (n >= NUM)); 12 /* 注意:输入的n个整数,放入a[0]至a[n-1]中,a[n]在查找时用作辅助空间 */ 13 printf("Enter %d integer numbers: ", n); 14 for (i = 0;i < n;i++) 15 { 16 scanf("%d", a + i); 17 } 18 return n; 19 } 20 21 int search(int * a, int x, int n) 22 { 23 int i, p; /* 查找开始 */ 24 i = 0; /* 从a[0]元素开始查找 */ 25 a[n] = x; /* 把待查找的数放入a[n]中 */ 26 while (x != a[i]) 27 { 28 i++; 29 } 30 /* 只要x值等于当前a[i]的值,则推出循环,否则i后移一位 */ 31 if (i == n) 32 { 33 p = -1; /* 没找到 */ 34 } 35 else p = i; /* 找到 */ 36 return p; 37 } 38 39 main() 40 { 41 int a[NUM], x, n, p; /* 暂定数组含30个元素,下标的上限为29 */ 42 n = arrin(a); 43 printf("Enter the number to search:x="); 44 scanf("%d", &x); 45 p = search(a, x, n); 46 if (p != -1) 47 { 48 printf("%d index is:%d ", x, p); /* 输出x所在下标 */ 49 } 50 else printf("%d is not found! ", x); /* 输出没找到信息 */ 51 }
例9.8 w 数组中存放 n 个数据,编写函数删除下标为 k 的元素中的值。
以下程序中,调用了 getindex、arrout 和 arrdel 三个函数。getindex 用以输入所删元素的下标,函数中对输入的下标进行检查,若越界,则要求重新输入,直到正确为止;arrout 用以输出数组中的数据;arrdel 进行所要求的删除操作。
1 #include <stdio.h> 2 #define NUM 10 /* 假定数组含有10个元素 */ 3 int arrdel(int *, int, int); /* 函数说明语句 */ 4 void arrout(int *, int); /* 函数说明语句 */ 5 int getindex(int n); 6 main() /* 用置初值的方法给数组置数 */ 7 { 8 int n, d, a[NUM] = { 21,22,23,24,25,26,27,28,29,30 }; 9 n = NUM; 10 printf("Output primary data: "); /* 输出原始数据 */ 11 arrout(a, n); 12 d = getindex(n); 13 n = arrdel(a, n, d); 14 printf("Output the data after delete: "); /* 输出删除后的数据 */ 15 arrout(a, n); 16 } 17 18 void arrout(int w[], int m) 19 { 20 int k; 21 for (k = 0;k < m;k++) 22 { 23 printf("%d ", w[k]); 24 } 25 printf(" "); 26 } 27 28 int arrdel(int * w, int n, int k) 29 { 30 int i; 31 for (i = k;i < n - 1;i++) 32 { 33 w[i] = w[i + 1]; /* i+1替换i */ 34 } 35 n--; /* 删除后数据个数减1 */ 36 return n; 37 } 38 39 getindex(int n) 40 { 41 int i; 42 do /* 当指定的下标值落在数据所在下标范围内时,退出循环,返回该下标值 */ 43 { 44 printf(" Enter the index [0<=i<%d]:", n); /* 输入待删元素的下标 */ 45 scanf("%d", &i); 46 } while (i<0 || i>n - 1); 47 return i; 48 }
例9.9 用选择法对数组中的数进行排序(按由小到大顺序)。
1 #include <stdio.h> 2 #define NUM 6 3 void arrsort(int[], int); 4 void arrout(int *, int); 5 main() 6 { 7 int a[NUM] = { 5,7,4,2,8,6 }; 8 arrout(a, NUM); /* 输出a数组中原始数据 */ 9 arrsort(a, NUM); /* 对a数组中的数进行排序 */ 10 arrout(a, NUM); /* 输出排序后a数组中的数据 */ 11 } 12 13 void arrsort(int * a, int n) 14 { 15 int i, j, p, t; 16 for (j = 0;j < n - 1;j++) /* n个数进行n-1次选择 */ 17 { 18 p = j; /* 先使p指向排序范围的第一个元素 */ 19 for (i = j + 1;i < n;i++) 20 { 21 if (a[p] > a[i]) 22 { 23 p = i; /* 使p指向a[j]到a[n-1]之间的最小元素的位置 */ 24 } 25 } 26 if (p != j) 27 { 28 t = a[j]; 29 a[j] = a[p]; 30 a[p] = t; /* 如果排序范围的第一个元素不是最小的元素,则将最小的元素的值与排序范围的第一个元素中的值进行对调 */ 31 } 32 } 33 } 34 35 void arrout(int a[], int n) 36 { 37 int i; 38 for (i = 0;i < n;i++) 39 { 40 printf("%d", a[i]); 41 } 42 putchar(' '); 43 }
考点:
1
行列下标下限为 0,上限为 n-1
2
一定要把两个下标分别放在两个方括号内
int a[4] [2]合法
int a[0, 1]不合法
3
a[i] [j] 表示第 (i + 1) 行第 (j + 1) 列
第 m 行第n列:a[m-1] [n-1]
int a[m] [n] 该二维数组右下角位置的元素是 a[m - 1] [n - 1]
是否存在多维数组?
不存在多维数组。
因为内存是线性一维的。
n维数组可以当作每个元素是 n - 1 维数组的一维数组
比如:
int a[3][4]
该数组是含有3个元素的一维数组
只不过每个元素都可以再分成4个小元素
int a[3][4][5]
该数组是含有3个元素的一维数组
只不过每个元素都是4行5列的二维数组
例9.10 通过键盘给 2*3 的二维数组输入数据,第一行赋1、2、3,第二行赋10、20、30,然后按行输出此二维数组。
1 #include <stdio.h> 2 main() 3 { 4 int a[2][3], i, j; 5 printf("Enter data by line: "); 6 for (i = 0;i < 2;i++) 7 { 8 for (j = 0;j < 3;j++) 9 { 10 scanf("%d", &a[i][j]); 11 } 12 } 13 printf("Output a 2-dimension array: "); 14 for (j = 0;j < 2;j++) 15 { 16 for (i = 0;i < 3;i++) 17 { 18 printf("%4d", a[j][i]); 19 } 20 printf(" "); 21 } 22 for (i = 0;i < 3;i++) 23 { 24 for (j = 0;j < 2;j++) 25 { 26 printf("%4d", a[j][i]); 27 } 28 printf(" "); 29 } 30 }
输出格式:
Enter data by line:
1 2 3 10 20 30
Output a 2-dimension arra
1 2 3
10 20 30
1 10
2 20
3 30
请按任意键继续. . .
例9.11 编写程序,通过调用随机函数给 5*6 的二维数组元素赋10~40范围内的整数,求出二维数组每行元素的平均值。
1 #include <stdio.h> 2 #include <stdlib.h> 3 #define M 6 /* 每行6列 */ 4 #define N 5 /* 数组包含5行 */ 5 void getdata(int(*)[M]); /* 得到随机数 */ 6 void lineave(int[][M], float *); /* 求每行的平均值 */ 7 void outdata(int[N][M], float *); /* 输出数据 */ 8 main() 9 { 10 int r[N][M]; /* 用整型数组r存放随机数 */ 11 float ave[N]; /* 用ave数组存放每行的平均值 */ 12 getdata(r); /* 输入数据 */ 13 lineave(r, ave); /* 求r数组每行的平均值放在ave数组中 */ 14 outdata(r, ave); /* 输出数据 */ 15 } 16 17 void getdata(int(*sp)[M]) 18 { 19 int i, j, x; 20 for (i = 0;i < N;i++) 21 { 22 j = 0; 23 while (j < M) 24 { 25 x = rand() % 41; /* 产生0到40的随机数 */ 26 if (x >= 10) /* 只有产生的随机数大于或等于10时才放入数组中 */ 27 { 28 sp[i][j] = x; 29 j++; 30 } 31 } 32 } 33 } 34 35 void lineave(int s[][M], float * a) /* 求每行的平均值 */ 36 { 37 int i, j; 38 float ave; 39 for (i = 0;i < N;i++) 40 { 41 ave = 0.0; 42 for (j = 0;j < M;j++) 43 { 44 ave = ave + s[i][j]; 45 } 46 a[i] = ave / M; 47 } 48 } 49 50 void outdata(int sp[N][M], float a[]) 51 { 52 int i, j; 53 printf("Output the result: "); 54 for (i = 0;i < N;i++) 55 { 56 for (j = 0;j < M;j++) 57 { 58 printf("%4d", sp[i][j]); 59 } 60 printf(":%6.2f ", a[i]); 61 } 62 putchar(' '); 63 }
9.12 行列互换
1 #include <stdio.h> 2 main() 3 { 4 int a[3][3] = { {1,2,3},{4,5,6},{7,8,9} }; 5 int i, j, t; 6 for (i = 0;i < 3;i++) 7 { 8 for (j = 0;j < 3;j++) 9 { 10 printf("%d ", a[i][j]); 11 } 12 printf(" "); 13 } 14 for (i = 0;i < 3;i++) 15 { 16 for (j = i + 1;j < 3;j++) 17 { 18 t = a[i][j]; 19 a[i][j] = a[j][i]; 20 a[j][i] = t; 21 } 22 } 23 for (i = 0;i < 3;i++) 24 { 25 for (j = 0;j < 3;j++) 26 { 27 printf("%d ", a[i][j]); 28 } 29 printf(" "); 30 } 31 }