【C语言入门】笔记七 (数组上)

(emmm...第六章暂时跳过...)

第七章 数组

7.1

例7-1

输出所有大于平均数的数。输入n个整数(1≤n≤10),计算这些数的平均值,在输出所有大于平均值的数。

#include <stdio.h>
int main(void){
	int i,n;
	double average,sum;
	int a[10];
	
	printf("Enter:");
	scanf("%d",&n);
	if(n>=1 && n<=10){
		printf("Enter %d integers:",n);
		for(i=0;i<n;i++){
			scanf("%d",&a[i]);
		}
		sum=0;
		for(i=0;i<n;i++){
			sum=sum+a[i];
		}
		average=sum/n;
		printf("average=%.2f\n",average);
		printf(">average:");
		for(i=0;i<n;i++){
			if(a[i]>average){
				printf("%d ",a[i]);
			}
		}
		printf("\n");
	}else{
		printf("Invaild Value.\n");
	}
	return 0;
} 

程序中定义一个整数型数组a后,在内存中开辟了10个连续的单元,用于存放数组a的是个元素a[0]~a[9]的值,这些元素类型都是整型,相应的内存单元的存储内容即是例题中输入的十个数对应的位置。

在程序中使用数组,可以让一批相同类型的变量使用同一个数组变量名,用下标来相互区分,优美简洁,可读性好,便于使用循环结构。

7.1.2 一维数组的定义和引用

定义一个数组需要明确数组变量名,数组元素的类型和数组的大小(数组中的元素数量)。

一维数组的定义方式一般为:

类型名 数组名[数组长度];

 数组名指定数组中每个元素的类型;数组名是数组变量的名称,是一个合法的标识符

例如:int a[10]; 就是定义一个有10个整数元素的数组a(数组长度是一个常量)

数组名是一个地址常量,存放数组内存空间的首地址

...

7.1.3 一维数组的初始化

和简单变量的初始化一样,在定义数组时,也可以对数组元素赋初始值,一般形式为:

类型名 数组名[数组长度]={数值表};

例如:

int a[10]={0,1,2,3,4,5,6,7,8,9};

定义数组a,则a[0]为0,a[1]为1...

虽然C语言规定,只有静态储存的数组才能初始化,但是一般的C编译系统都允许对动态存储的数组赋初值。静态数组例如:

static int b[5]={1,2,3,4,5};

初始化静态数组b。静态存储的数组如果没有初始化,系统将自动给所有的数组元素赋0(不同编译器不同)

数组的初始化也可以针对部分元素,例如:

static int b[5]={1,2,3};

支队数组b的前3个元素赋初值,其余的元素的初值都为0

数组初始化时,如果对全部元素都赋了初值,就可以省略数组长度,例如:

int a[ ]={1,2,3,4,5,6,7,8,9,10};

此时系统会根据初值的个数自动给出数组的长度

显然,如果只对部分元素初始化,数组长度时不能省略的。为了改善程序的可读性,尽量避免出错,不管是否对全部数组元素赋初值,都不省略数组长度。

7.1.4 使用一维数组编程

1. 选择排序法

练(原书中例7-5):输入一个正整数n(1<n≤10),再输入n个整数,用选择法将它们从小到大排列后输出

  • 第1步:在未排序的n个数(a[0]~a[n-1])中找到最小值,将它的值于a[0]的值交换;
  • 第2步:在剩下未排序的n-1个数(a[1]~a[n-1])中找到最小数,将它与a[1]的值交换;
  • ......
  • 第n-1步:在剩下未排序的两个数(a[n-2]和a[n-1])中找到最小数,将它与a[n-2]的值交换。

编写程序:

#include <stdio.h>
#define MAXN 10
int main(void){
	int a[MAXN],n,i,k,index,temp;
	scanf("%d",&n);
	for(i=0;i<=n-1;i++){
		scanf("%d",&a[i]);
	}
	for(k=0;k<=n-1;k++){ //选n次 
		index=k;
		for(i=k+1;i<=n-1;i++){ //比较时的每一次 
			if(a[index]>a[i]){ 
				index=i;
			}
		}
		temp=a[k];
		a[k]=a[index];
		a[index]=temp;
	}
	for(i=0;i<=n-1;i++){
		printf("%d ",a[i]);
	}
	return 0;
}

练(原书中例7-6):调查电视节目受欢迎程度。某电视台要调查观众对该台8个栏目的受欢迎情况,共调查了n(1≤n≤1000)位观众。现要求编写程序,输入每一位观众的投票情况(每位观众只能选择一个喜欢的栏目投票),统计输出各栏目的得票情况。

#include <stdio.h>
#define MAXN 8
int main(void){
	int i,n,respond;
	int count[MAXN+1]={0,0,0,0,0,0,0,0};
	printf("人数n=");
	scanf("%d",&n);
	for(i=1;i<=n;i++){
		scanf("%d",&respond);
		if(respond>=1 && respond<=8){
			count[respond]++;
		}
	}
	for(i=1;i<=MAXN;i++){
		printf("%4d %4d\n",i,count[i]);
	}
	return 0;
}

2. 二分查找法(重点)

练(原书中例7-7):设已有一个n(1≤n≤10)个元素的整型数组a,且按值从小到大有序排列。输入一个整数x,然后再数组中查找x,如果找到,输出相应的下标,否则,输出"Not found"。

查找和排序一样,都是程序设计的最基本的算法。对数组元素从头到尾进行遍历,一旦数组元素量很大,其查找的效率就不高。二分查找是查找效率较高的一种,但前提是数组元素必须有序的,算法思路如下:

n个元素的数组a已有序(假定a[0]到a[n-1]升序排列),用lowhigh两个变量来表示查找区间的端点元素的下标,即在a[low]~a[high]间去查找x。初始状态为low=0,high=n-1。首先要用查找的x与查找区间中间的中间位置元素a[mid](mid=(low+high)/2)比较,如果相等则找到,算法终止;如果x<a[mid],由于数组是升序排列的,则只要在a[low]~a[mid-1]内查找;如果x>a[mid],则只要继续在a[mid+1]~a[high]区间继续查找。也就是根据与中间元素比较的情况产生了新的区间端点元素下标值low、high,当出现low>high时算法终止,即不存在值为x的元素。

#include <stdio.h>
int main(void){
	int a[10]={1,2,3,4,5,6,7,8,9,10};
	int low,high,mid,i,n=10,x,index;
	
	printf("x=");
	scanf("%d",&x);
	low=0;
	high=n-1;
	while(low<=high){
		mid=(low+high)/2;
		if(a[mid]==x){
			index=mid;
			break;
		}else if(x>a[mid]){
			low=mid+1;
		}else{
			high=mid-1;
		}
	}
	if(low<=high){
		printf("Index:%d",index);
	}else{
		printf("Not found");
	}
	return 0;
}

练习7-2

求最大值及下标。输入一个正整数n(1<n≤10),再输入n个整数,输出最大值及其对应的最小下标,下标从0开始。

#include <stdio.h>
int main(void){
	int i,k,n,index,temp;
	int a[n-1];
	printf("n=");
	scanf("%d",&n);
	printf("Enter %d data:",n);
	for(i=0;i<=n-1;i++){
		scanf("%d",&a[i]);
	}
	for(k=0;k<=n-1;k++){ //循环n次 
		index=k; //将最小的数组底数赋值为k 
		for(i=k+1;i<=n-1;i++){ //每一次循环中将其与下面的数进行比对 
			if(a[index]<a[i]){
				index=i; //每一次比对将最小的数的底数赋给index 
			}
		}
		/* 将a[k]与a[index]的值交换 */ 
		temp=a[k];
		a[k]=a[index]; 
		a[index]=temp;		
	}
	for(i=0;i<=n-1;i++){
		printf("%4d%4d\n",i,a[i]);
	}
	return 0;
}

练习7-3

将数组中的数逆序存放。输入一个正整数n(1<n≤100),再输入n个整数,存入数组a中,先将数组a中的这n个数逆序存放,再按顺序输出数组a中的n个元素。

#include <stdio.h>
int main(void){
	int i,k,n,index,temp;
	printf("Enter n:");
	scanf("%d",&n);
	int a[n];
	printf("Enter data:");
	for(i=0;i<=n-1;i++){
		scanf("%d",&a[i]);
	}
	for(k=0;k<=n-1;k++){
		index=k;
		for(i=k+1;i<=n-1;i++){
			if(a[i]<a[index]){
				index=i;
			}
		}
		temp=a[k];
		a[k]=a[index];
		a[index]=temp;
	}
	for(i=0;i<=n-1;i++){
		printf("%d ",a[i]);
	}
	return 0;
}

练习7-4

找出不是两个数组共有的元素。输入一个正整数n(1<n≤10),再输入n个整数,存入一个数组中;然后输入一个正整数m(1<m≤10),再输入m个整数,存入第二个数组中,找出所有不是这两个数组共有的元素。

#include <stdio.h>
int main(void){
	int i,j,m,n,k=0;
	/*定义两个数组*/ 
	printf("Enter n:");
	scanf("%d",&n);
	int a[n];
	printf("Enter data:");
	for(i=0;i<=n-1;i++){
		scanf("%d",&a[i]);
	}
	printf("Enter m:");
	scanf("%d",&m);
	int b[m];
	printf("Enter data:");  
	for(i=0;i<=m-1;i++){
		scanf("%d",&b[i]);
	}
	
	for(i=0;i<=n-1;i++){ //将数组a与数组b比较,输出数组a与数组b的不同数 
		for(j=0;j<=m-1;j++){
			if(a[i]==b[j]){ //当遇到相同的就跳出循环 
				break;
			}
		}
		if(j==m){ //由于循环结构没被break时会使j=m,所以就可以认定此数为不相同的数 
			printf("%d ",a[i]);
		}
	}
	/*同理输出数组b中的不同数*/
	for(i=0;i<=m-1;i++){
		for(j=0;j<=n-1;j++){
			if(b[i]==a[j]){
				break;
			}
		}
		if(j==n){
			printf("%d ",b[i]);
		}
	}
	return 0;
} 

7.2 

7.2.2 二维数组的定义和引用

C语言支持多维数组,最常见的多维数组为二维数组,主要用于二维表和矩阵

1. 定义

二位数组的定义形式为:

类型名 数组名[行长度][列长度];

类型名指定数组中的每个元素的类型,数组名是数组变量的名称,是一个合法的识别符,行长度和列长度是整数常量表达式,分别给定数组的行数和列数。

定义一个二位数组a,3行2列,一共6个元素

int a[3][2];

2. 引用

引用二位数组的元素要指定两个下标,即行下标和列下标,形式为:

数组名[行下标][列下标];

二维数组在内存中的存放形式 :

7.2.3 二维数组的初始化

在定义二维数组时,也可以对数组元素赋初值,二维数组的初始化方法有两种:

1.分行赋初值

类型名 数组名[行长度][列长度]={{初值表0},{初值表1},...{初值表n}};

例如:

int a[3][3]={{1,2,3},{4,5,6},{7,8,9}};

此时,a数组的各元素为:

2.顺序赋初值

类型名 数组名[行长度][列长度]={初值表};

 根据数组元素在内存中的存放顺序,会把初值表中的数据依次赋给元素

例如:

int a[3][3]={1,2,3,4,5,6,7,8,9};

 等价于

int a[3][3]={{1,2,3},{4,5,6},{7,8,9}};

二维数组初始化时,如果对全部元素都赋了初值,或分行赋初值时,在初值表中列出了全部行,就可以忽略行的长度,但是不建议这样做

7.2.4 使用二维数组编程

矩阵的术语与二维数组下标的对应关系:

例7-9

方阵转置。输入一个正整数n(1<n≤6),根据下式生成一个n × n的方阵,将该方阵转置(行列互换)后输出。

#include <stdio.h>
#define MAXN 6
int main(void){
	int i,j,n,temp;
	int a[MAXN][MAXN];
	
	printf("Enter n:");
	scanf("%d",&n);
	for(i=0;i<n;i++){
		for(j=0;j<n;j++){
			a[i][j]=i*n+j+1;
		}
	}
	
	for(i=0;i<n;i++){
		for(j=0;j<n;j++){
			if(i<=j){
				temp=a[i][j];
				a[i][j]=a[j][i];
				a[j][i]=temp;
			}
		}
	}
	
	for(i=0;i<n;i++){
		for(j=0;j<n;j++){
			printf("%4d",a[i][j]);
		}
		printf("\n");
	}
	
	return 0;
}

练习7-7

矩阵计算。读入一个正整数n(1≤n≤6),再读入n阶方阵a,计算该矩阵除副对角线、最后一列和最后一行以外的所有元素之和。副对角线为从矩阵的右上角至左下角的连线。

#include <stdio.h>
#define MAXN 6
int main(void){
	int i,j,n,sum=0;
	int a[MAXN][MAXN];
	
	printf("Enter n:");
	scanf("%d",&n);
	
	for(i=0;i<=n-1;i++){
		for(j=0;j<=n-1;j++){
			a[i][j]=i*n+j+1;
		}
	}
	
	for(i=0;i<=n-1;i++){
		for(j=0;j<=n-1;j++){
			if(i+j!=n-1&&i!=n-1&&j!=n-1){
				sum+=a[i][j];
			}
		}
	}
	
	printf("%d",sum);
	return 0;
}

- 先写到这里,下次笔记补上数组部分 🙄 -

整理自书籍《C语言程序设计》

如有错误,欢迎纠正!

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值