第七章 数组

#include <stdio.h>
#define MAXN 10
int main()
{	
	int i,index,k,n,temp;
	int a[MAXN];

	printf("Enter n:");
	scanf("%d",&n);
	printf("Enter %d interger:",n);
	for(i=0;i<n;i++)
		{
			scanf("%d",&a[i]);
		}
	for(k=0;k<n-1;k++)
	{index=k;
	 for(i=k+1;i<n;i++)
	 {if(a[i]<a[index]){
		 index=i;
		}
	 }
	temp=a[index];
	a[index]=a[k];
		a[k]=temp;
	}
	printf("After sorted:");
	for(i=0;i<n;i++)
	{
		printf("%d",a[i]);
	
	}
	printf("\n");

	return 0;
}

程序介绍:这里是用选择排序来进行排序的

选择排序的算法步骤如下:

第1步:在未排序的n个数(a【0】~a【n-1】)中找到最小数,将它与a【0】交换;

第2步:在剩下未排序的n-1个数(a【1】~a【n-1】)中找到最小数,将它与a【1】交换;

…………

第n-1步:在剩下未排序的数2个数(a【n-2】~a【n-1】)中找到最小数,将它与a【n-2】交换。

流程图如下:

现在,介绍一维数组的定义和引用

一维数组的定义和引用 

1.什么是数组?

数组是一些具有相同类型的数据的集合,数组中的元素按照一定的顺序排列存放。同一数组中的每一个元素具有相同的数据类型,有统一的标识符即数组名,用不同的序号即下标来区分数组中的各元素。

在定义数组后,系统根据数组中元素的类型及个数在内存分配了一段连续的存储单元用于存放数组中的各个元素,并对这些单元进行连续编号,即下标,以区分不同的单元。每个单元所需的字节数由数组定义时给出的类型来确定。

假设int类型占用2个字节,前面定义的数组a的起始地址是4010,则其内存分配形式如下图,每一个元素需2个字节,一共20个字节。由图可看出,只要知道了数组首元素的地址以及每个元素所需的字节数,其余各个元素的存储地址均可计算得到。

C语言规定,数组名表示该数组所分配连续内存空间中第一个单元的地址,即首地址。由于数组空间一经分配之后在运行过程中不会改变,因此数组名是一个地址常量,不允许修改。

2.定义

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

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

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

类型名指定数组中每个元素的类型;数组名是数组变量(以下简称数组)的名称,是一合法的标识符;数组长度是一个整形常量表达式,设定数组的大小。

int a[10]     //定义一个有10个整形元素的数组a

3.引用

定义数组后,就可以使用它了。C语言规定了,只能应用单个的数组元素,而不是一次引用整个数组。

数组元素的引用要指定下标,形式为:

        数组名[下标]

下表可以是整形表达式。它的合理取值范围是[0,数字长度-1],前面定义的数组a就有10元素a[0],a[1],……,a[9],注意不能使用a[10]。这些数组元素在内内存中按下标递增连续存储。

数组元素的使用方法与同类型的变量完全相同。例如

        int k,a[10];

定义了整形变量k和整形数组a。在可以使用整形变量的任何地方,都可以使用整形数组a的元素。

例如:

        k=3;

        a[0]=23;

        a[k-2]=a[0]+1;

        scanf("%d",&a[9]);

都合法。

注意:区分数组的定义和数组元素的引用,两者都要用到“数组名[整型表达式]”。定义数组时,方括号内是常量表达式,代表数组长度,它可以包括常量和符号常量,但不能包含变量。也就是说,数组的长度在定义时必须指定,在程序的运行过程中是不能改变的。而引用数组元素时,方括号内是表达式,代表下标,可以是变量,下标的合理取值范围是[0,数组长度-1]。

一维数组的初始化

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

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

初值表中依次放着数组元素的初值。例如

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

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

        static  int  b[5]={1,2,3,4,5};           //初始化静态数组b。

静态数组如果没有初始化,系统自动给所有的数组元素赋0.即

        static  int b[5];

等价于

        static  int b[5]={0,0,0,0,0};

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

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

这里,只对数组b的前3个元素赋初值,其余元素的初值为0。即b[0]为1,b[1]为2,b[2]为3,b[3]和b[4]都为0。

        int fib[20]={0,1};

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

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

此时,系统会根据初值的个数自动给出数组的长度。等价于:

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

二分法查找

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


二分查找法的算法步骤如下:

 设n个元素的数组a已有序(假定a[0]到a[n-1]升序排列),用low和high两个变量来查找区间的端点元素的下标,即在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>
#define MAXM 6
#define MAXN 6
int main()
{	
	int col,i,j,m,n,row;
	int a[MAXM][MAXN];
	printf("Enter m,n:");
	scanf("%d%d",&m,&n);
	printf("Enter %d interger:\n",m*n);
	for(i=0;i<m;i++){
		for(j=0;j<n;j++){
			scanf("%d",&a[i][j]);
	}
	}
	row=col=0;
	for(i=0;i<m;i++){
		for(j=0;j<n;j++){
			if(a[i][j]>a[row][col]){
	row=i;
	col=j;
	}
	}
	}
	printf("max=a[%d][%d]=%d\n",row,col,a[row][col]);
	return 0;
}

二维数组的定义与引用

1.定义

二维数组的定义形式:

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

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

例:int a[3][2]; // 定义一个二维数组a,3行2列,一共6个数组

2.引用

应用二维数组的元素要指定两个下标,即行下标和列下标:

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

行下标的合理取值范围是[0,行长度-1],列下标的合理取值范围是[0,列长度-1]。对前面定义的数组a,其行下标取值范围是[0,2],列下标取值范围是[0,2],6个元素分别是a[0][0],a[0][1],a[1][0],a[1][1],a[2][0],a[2][1].可以表示一个3列2行的矩阵。注意下标不要越界。

二维数组的元素在内存中按照行/列方式存放,即先存放第0行的元素,在存放第1行的元素……其中每一行的元素在按照列的顺序存放。如下图。

 

二维数组的初始化

1.分行赋值法

一般形式:

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

把初值表k中的数据依次赋给第k行的元素。例如:

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

初始化数组a,此时a中各元素如下

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

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

只对b数组第0行的全部元素和第2行的前两个元素赋初值,其余元素的初值都是0.

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}};

如果只对部分元素赋初值,要注意初值表中数据的书写顺序。例如

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

等价于

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

由此可见,分行赋初值的方法直观清晰,不易出错,是二维数组初始化最常用的方法。

二维数组初始化时,如果对全部元素都赋了初值,或者分行赋初值时,在初值表中列出了全部行,就可以省略行长度,例如

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

等价于

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

与一维数组的情况类似,建议读者定义二维数组时,不要省略长度。

#include<stdio.h>
#include<string.h>
void f(int a1[3][3]){
	int i,j,t;
	for(i=0;i<3;i++){
		for(j=0;j<3;j++){
			t=a1[j][i];
			a1[j][i]=a1[i][j];
			a1[i][j]=t;
		}
	}
}
main(){
	int a[3][3];
	int i,j;
	for(i=0;i<3;i++){
		for(j=0;j<3;j++){
				scanf("%d",&a[i][j]);//输入数据
		}
		printf("\n");
	}
	f(a); //调用了上面写的函数
	for(i=0;i<3;i++){
		for(j=0;j<3;j++){
			printf("%d ",a[j][i]); //有空格 且顺序换了
		}
		printf("\n");
	}
	return 0;
}

浙大版这里的程序有问题,用vc6运行死活都是垃圾值,故这里借一下别人的轮子。

字符串 

#include <stdio.h>
#define MAXLINE 80
int main()
{
	int i,k;
	char line [MAXLINE];

	printf("Enter a string:");
	k=0;
	while((line[k]=getchar())!='\n'){
	k++;
	}
	line[k]='\0';

	i=0;
	k=k-1;

	while(i<k)
	{if(line[i]!=line[k]){
		break;
	}
	i++;
	k--;
	}
	
	if(i>=k){
		printf("It is a palindrome \n");
	}else{
		printf("It is not a palindrome\n");
	}
	return 0;

}

又是笔误。。。在i++;k++;后面的}在原书上是没有对应括号的,这导致报错,但是这个括号是在if后面的,希望浙大的老师能好好的看一遍书,不要犯小儿科错误了。。。

一维字符数组和字符串

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值