C语言学习笔记 初识数组
1.求一组数的平均数,并输出大于该值的所有数。
#include <stdio.h> //求一组数的平均数,并输出大于该值的所有数。输入-1时结束输入。 int main() { int x; double sum = 0; int cnt = 0; int number[100];//定义数组 scanf("%d", &x); while (x!=-1) { number[cnt] = x;//对数组中的元素赋值 //printf("%d ", number[cnt]); cnt++; sum += x; //printf("%.2f", sum); scanf("%d", &x); } if (cnt > 0) { double average = sum / cnt; printf("average=%.2f\n", average); int i = 0; for ( i = 0; i < cnt; i++)//遍历数组 { if (number[i]>average)//使用数组中的元素 { printf("%d ", number[i]); } } } return 0; } imput:1 2 3 4 5 6 7 8 9 10 -1 output: average=5.50 6 7 8 9 10
2. 数组的使用
定义数组
<类型> 变量名称[元素数量] int grades[100] double number[20]
数组是一种容器,,特点是:其中所有的元素具有相同的数据类型;一旦创建不能改变大小;数组中的元素在内存中是连续依次排列的。
数组的单元:数组的每个单元就是数组类型的一个变量,使用数组时放在[]中的数字叫做下标或索引,下标从0开始计数。
有效的下标范围:[0,数组的大小 - 1] 编译器和运行环境都不会检查数组下标是否越界,无论是对数组单元做读还是写。这是程序员的
责任来保证程序只使用有效的下标值。
程序:输入数量不确定的[0,9]范围内的整数,统计每一种数字出现的次数,输入-1结束。
#include <stdio.h> int main() { const int number = 10;//数组的大小 int x; int i; int count[number];//定义数组 for (i = 0; i < number; i++) { //初始化数组 count[i] = 0; } scanf("%d", &x); while (x != -1) { if (x >= 0 && x <= 9) { count[x]++;//数组参与运算 } scanf("%d", &x); } for (i = 0; i < number; i++) { //遍历数组输出 printf("%d:%d\n", i, count[i]); } return 0; } 1 1 2 3 3 3 6 -1 0:0 1:2 2:1 3:3 4:0 5:0 6:1 7:0 8:0 9:0
DEV-C++使用的编译器是GCC,它允许使用变量作为数组的长度定义数组。
VC的编译器不是GCC,它不允许你这样做。在VS中会出错,DEV-C++则完全不会。
3. 数组运算
//数组的集成初始化
int a[] = { 0,1,2,3,4,5 };
int a[] = { 0 };
//集成初始化时的定位C99only
int a[10] = { [0] = 2,[2] = 3,6,};
//用[n]在初始化数据中给出定位;
//没有定位的数据接在前面的数据后面;
//其他的位置值补0;
//也可以不给出数组的大小,让编译器算;
//特别适合初始数据稀疏的数组。
//数组的大小
//sizeof给出整个数组所占据内容的大小,单位是字节
sizeof(a)/sizeof(a[0])
//数组的赋值
//数组变量本身不能被赋值,要把数组中的所有元素交给另一个数组,必须采用遍历
//数组作为参数时,不能在[]中给出数组的大小,不能再利用sizeof来计算数组的元素个数,必须用另一个参数来传入数组的大小
4. 数组例子
求素数
法一:
int isPrime(int x, int knownPrime[], int numberofknownPrime);//判断能否被已知的且<x的素数整除 int main() { const int number = 10; //int prime[number] = {2};//VS中不支持变量定义数组元素个数,DEVc++中使用变量定义长度时, //不可在定义时同时进行初始化赋值,需要在之后进行赋值。 //int prime[10]={2,0,0,0,0,0,0,0,0,0}; int prime[number]; prime[0] = 2; int j; for(j = 1;j<number;j++){ prime[j] = 0; } int i = 3; int count = 1; while(count < number){ if(isPrime(i, prime, count)){ prime[count++] = i;//相当于prime[count] = i;count++;将得到的素数添加到数组中去。 } i++; } for(i = 0;i<count;i++){ printf("%d",prime[i]); if((i+1)%5) printf("\t"); else printf("\n"); } return 0; } int isPrime(int x, int knownPrime[], int numberofknownPrime) { int ret = 1; int i; for(i = 0;i<numberofknownPrime;i++){ if(x%knownPrime[i] == 0){ ret = 0; break; } } return ret; } output: 2 3 5 7 11 13 17 19 23 29
关于i++与++i
即i++返回的是i未更新的原值,++i返回的是更新后的值。
法二:构建素数表
构建素数表: 1.令x = 2 2.将2x, 3x, 4x乃至ax < n标记为非素数 3.令x为下一个没有被标记为非素数的数,重复2;直到所有的数都被尝试完毕。 伪代码: 欲构造n以内(不包含n)的素数表 1.开辟prime[n],初始化其所有元素为1,prime[x]为1表示x为素数 2.令x为2 3.如果x为素数,则对于(i = 2; i * x < n; i++)令prime[x] = 0 4.令x++,如果x<n则重复3,否则结束。
程序:
int main() { const int maxnumber = 15; //int isPrime[number]; int isPrime[15]; int x; int i; for (i = 0; i < maxnumber; i++) { isPrime[i] = 1; } //for test------------------------ printf("\t"); for (i = 2; i < maxnumber; i++) { printf("%d\t", i); } printf("\n"); //for test--------------------- for (x = 2; x < maxnumber; x++) { if (isPrime[x]) { for (i = 2; i * x < maxnumber; i++) { isPrime[i * x] = 0; } } //for test-------------- printf("%d\t", x); for (i = 2; i < maxnumber; i++) { printf("%d\t", isPrime[i]); } printf("\n"); } for (i = 2; i < maxnumber; i++) { if (isPrime[i]) { printf("%d\t", i); } } return 0; }
输出:
2 3 4 5 6 7 8 9 10 11 12 13 14 2 1 1 0 1 0 1 0 1 0 1 0 1 0 3 1 1 0 1 0 1 0 0 0 1 0 1 0 4 1 1 0 1 0 1 0 0 0 1 0 1 0 5 1 1 0 1 0 1 0 0 0 1 0 1 0 6 1 1 0 1 0 1 0 0 0 1 0 1 0 7 1 1 0 1 0 1 0 0 0 1 0 1 0 8 1 1 0 1 0 1 0 0 0 1 0 1 0 9 1 1 0 1 0 1 0 0 0 1 0 1 0 10 1 1 0 1 0 1 0 0 0 1 0 1 0 11 1 1 0 1 0 1 0 0 0 1 0 1 0 12 1 1 0 1 0 1 0 0 0 1 0 1 0 13 1 1 0 1 0 1 0 0 0 1 0 1 0 14 1 1 0 1 0 1 0 0 0 1 0 1 0 2 3 5 7 11 13
5. 二维数组
二维数组的遍历
for (i = 0; i < 3; i++) { for (j = 0; j < 5; j++) { a[i][j] = i * j; } }
实例:
1 //tic-tac-toe小游戏 2 3 int main() 4 { 5 const int size = 3; 6 int board[size][size]; 7 int i, j; 8 int numofx; 9 int numofo; 10 int result = -1;//-1:没人赢 1:x赢 0:o赢 11 12 //读入矩阵 13 for (i = 0; i < size; i++) { 14 for (j = 0; j < size; j++) { 15 scanf("%d", &board[i][j]); 16 } 17 } 18 //检查行 19 for (i = 0; i < size && result == -1; i++) { 20 numofx = numofo = 0; 21 for (j = 0; j < size; j++) { 22 if (board[i][j] == 1) { 23 numofx++; 24 } 25 else { 26 numofo++; 27 } 28 } 29 if (numofo == size) { 30 result = 0; 31 } 32 else if (numofx == size) { 33 result = 1; 34 } 35 } 36 37 //检查列 38 if (result == -1) { 39 for (j = 0; j < size; j++) { 40 numofo = numofx = 0; 41 for (i = 0; i < size; i++) { 42 if (board[i][j] == 1) { 43 numofx++; 44 } 45 else { 46 numofo++; 47 } 48 } 49 if (numofo == size) { 50 result = 0; 51 } 52 else if (numofx == size) { 53 result = 1; 54 } 55 } 56 } 57 58 //检查主对角线 59 if (result == -1) { 60 numofo = numofx = 0; 61 for (i = 0; i < size; i++) { 62 if (board[i][i] == 1) { 63 numofx++; 64 } 65 else { 66 numofo++; 67 } 68 } 69 if (numofo == size) { 70 result = 0; 71 } 72 else if (numofx == size) { 73 result = 1; 74 } 75 } 76 77 //检查副对角线 78 if (result == -1) { 79 numofo = numofx = 0; 80 for (i = 0; i < size; i++) { 81 if (board[i][size - i - 1] == 1) { 82 numofx++; 83 } 84 else { 85 numofo++; 86 } 87 } 88 if (numofo == size) { 89 result = 0; 90 } 91 else if (numofx == size) { 92 result = 1; 93 } 94 } 95 96 return 0; 97 }
二维数组的初始化
a[][5] = { {1,2,3,4,5}, {2,3,4,5,6}, }; 列数是必须给出的,行数可以由编译器来数; 每行一个{},逗号分隔; 最后的逗号可以存在,有古老的传统; 如果省略,表示补零; 也可以用定位(*C99 ONLY)