C语言丨数组

知识点

一维数组

定义以及初始化
一维数组的一般形式为:类型说明符 数组名[整型常量表达式]={初值表};
注意:
1、数组名表示该数组在内存的起始地址,是一个地址常量,其值不能被改变.
如char s[10]=“remind”;puts(s+2);输出结果为mind.s表示数组的起始地址,s+2表示数组第3个元素 的地址.
2、 数组在逻辑上相邻,在物理结构上也占据相邻的地址.如果存储空间不够会直接报错.
3、不能在方括号中用变量来表示元素个数.
4、数组不初始化时,元素值为随机数; 部分初始化时,未赋值元素自动赋值为0.
一维数组应用举例
1、冒泡排序.输入10个学生的成绩并按升序排列输出.
2、二分法查找元素.输入分数查找是否有该分数并找到其位置.注意使用二分法查找要求数组中的数据是已经排好顺序的数据.

#include <stdio.h>
int main()
{
	int score[10],i,j,temp;
	int low=0,high=9,mid,t,flag=0;//t为需要查找的成绩
	printf("please input 10 students' score:\n");
	for(i=0;i<10;i++)
		scanf("%d",&score[i]);

	for(i=0;i<9;i++)//冒泡排序需要循环n*(n-1)/2次
		for(j=0;j<9-i;j++)
			if(score[j]>score[j+1])
			{
				temp=score[j];
				score[j]=score[j+1];
				score[j+1]=temp;
			}

	for(i=0;i<10;i++)
	{
		printf("%-4d",score[i]);
	}
	printf("\n");

	printf("input the score you want:");//二分法查找元素
	scanf("%d",&t);
	while(low<=high)
	{
		mid=(low+high)/2;
		if(t==score[mid])
		{
			flag=1;
			break;
		}
		if(t>score[mid]) low=mid+1;
		else high=mid-1;
	}

	if(flag==1)
		printf("%d在第%d的位置上",t,mid+1);
	else printf("not exist");
	return 0;
}

二维数组

定义以及初始化
类型说明符 数组名 [常量表达式1] [常量表达式2]={初值表};
在C语言中,二维数组元素在内存中的排列顺序为“按行存放”,即对于数组a[m][n],先存放a[0]的n个元素,再排a[1]中的n个元素.若部分元素赋初始值,其余元素自动赋0.
例如:int a[3][5]={{90},{80},{92}}相当于int a[3][5]={{90,0,0},{80,0,0},{92,0,0}}.
二维数组应用举例
1、定义一个3x4的矩阵,对其中12个元素赋值,并输出该矩阵;
2、求矩阵中的最大值及其在数组中的位置.

#include <stdio.h>
int main()
{
	int matrix[3][4],i,j;
	int max,row=0,col=0;
	printf("请输入12个整数:\n");//输入矩阵
	for(i=0;i<3;i++)
		for(j=0;j<4;j++)
			scanf("%d",&matrix[i][j]);

	printf("矩阵为:\n");
	for(i=0;i<3;i++)//输出矩阵
	{
		for(j=0;j<4;j++)
			printf("%4d",matrix[i][j]);
	    printf("\n");//输出一行元素之后要另取一行
	}

	max=matrix[0][0];//找出最大值
	for(i=0;i<3;i++)
		for(j=0;j<4;j++)
			if(max<matrix[i][j]) 
			{
					max=matrix[i][j];
					row=i+1;
					col=j+i;
			}

	printf("矩阵中的最大值在%d行%d列,为%d",row,col,max);
	return 0;
}

字符数组

定义以及初始化
一维字符数组:char 数组名[常量表达式];
二维字符数组:char 数组名[常量表达式][常量表达式];
注意:对逐个字符赋予初值,数组长度与字符数相等,系统不要求最后一个字符为‘\0’,也不会自动添加空字符;若使用字符串赋初值,数组长度应该等于字符数加一来存放空字符‘\0’.例如:
char str[3]={‘a’,‘b’,‘c’};
char str[6]={China};或可以写为char str[6]=“China”;
字符串的输入与输出
1、使用scanf和printf函数对字符串输入/输出.
2、字符串输入/输出函数gets/puts.
例如:
char string[80];
gets(string);
puts(string);
注意数组名放入括号中作为gets的参数.
puts函数的功能是输出一个字符串,若有声明"char s[10]=“remind”;",执行“puts(s+2);”后的输出结果是mind.s表示数组的起始地址,s+2表示数组第二个元素的地址.
字符串处理函数
头文件string.h给出了以下四种函数得声明:
1、字符串连接函数strcat.
格式:strcat(数组名1,数组名2)
功能:把字符数组2中的字符串连接到字符数组1中字符串的后面,并去掉字符数组1中的字符串的字符串标志’\0’.故数组1的空间必须定义得足够大.
2、字符串复制函数strcpy.
格式:strcpy(s1,s2)
功能:把s2中的字符串连同’\0’复制到s1中.
3、字符串长度函数strlen.
格式:strlen(字符数组名)
功能:获得字符串的实际长度,不包含’\0’.该函数的功能等同于如下代码:

int strLength=0;
char ch,str[20];

ch=str[0];
	while (ch!='\0')
	{
		strLength+=1;
		ch=str[strLength];
	}
//此时有strLength=strlen(str)

注意数组定义的类型,int型一个数字4字节,char型一个数字1字节.
4、字符串比较函数strcmp.
格式:strcmp(s1,s2)
功能:将两个字符串从左至右逐个字符按照ASCII码值进行比较.
s1=s2,函数返回值=0;
s1>s2,函数返回值>0;
s1<s2,函数返回值<0.
注意单个字符ASCII码的大小比较可以直接使用>/</=,整个字符串的比较才需要strcmp.

易错

1、scanf遇到空格即停止,不输入空格后的字符.printf采用"%s"格式输出,遇到‘\0’时才会停止输出.
2、若有声明"char s1[10]=“ABCDE”,s2[10]=“A\0”;“,则语句"printf(”%d",strlen(strcpy(s1,s2)));“的输出结果是3.
解析:strcpy(s1,s2),将s2中的字符串复制到s1中,然后strlen计算s1字符串长度.字符串长度为3,故输出3.注意,两个反斜杠表示一个反斜杠,是转义字符.
3、区分sizeof和strlen,sizeof(string)计算数组string在内存中的字节数,看数组定义的大小.而strlen(string)计算的是字符串长度.
4、使用strcpy函数,将数组a中的字符串完全复制到另一个数组b中,则数组b之前的字符都被覆盖.
5、使用带%s格式符的scanf()函数读入字符串时,不需要添加&,即不要写成:scanf(”%s",&str),因为编译器会自动将str作为数组首地址来处理.
6、char s1[10]={0},s2[10]=“books”,则s1存放的是空串,strcat(s1,s2)就能将字符串"books"赋给s1保存.
7、数组名作为函数参数时,编译将实参的首地址传递给形参,这两个数组共享一个内存空间,在函数中对形参数组元素的操作就是对实参数组元素的操作.对形参做出了改变,同时就改变了主函数中实参数组的值,注意区别普通变量作为参数时的情况.

程序设计

1、输入30个学生的单科成绩,输出高于平均分的成绩.

#include<stdio.h>
int main()
{
    float score[30],sum=0,average=0;
    int i;

    for(i=0;i<30;i++)
    {
          scanf("%f",&score[i]);
          sum+=score[i];
    }
    
    average=sum/30;
    printf("The average score is %f",average);
    
    for(i=0;i<30;i++)
          if(score[i]>average)
          {
               printf("%f",score[i]);
               printf("\n");
          }
          
    return 0;
}

2、将一个数组中的值按逆序重新存放.

例如,原来顺序为8,6,5,3,1。要求改为1,3,5,6,8.
算法思想:将数组元素的第一个与最后一个元素交换位置,第二个元素与倒数第二个元素交换位置.需要注意的是,只能遍历数组的一半元素,如果遍历整个数组,每个元素都做了两次交换,最终又回到原来的位置上.

#include <stdio.h>
int main()
{
    int a[5]={1,3,5,6,8},i,j,middle;
    for(i=0;i<2;i++)//
        {middle=a[i];
        a[i]=a[4-i];
        a[4-i]=middle;}
    for(j=0;j<5;j++)
        printf("%d",a[j]);
    return 0; 
}

3.已有一个已按从小到大的要求排好序的整型数组a(设原来元素个数为5),要求输入一个整数后,按原来排序的规律将它插入数组中.

程序设计思路
1)输入一组从小到大的整数,存入数组a中;
2)输入需要插入的整数t;
3)查找插入位置的下标:从数组最后一个数a[i](i = N-1)开始,依次与t进行比较,如果t<a[i],把a[i]向后移一位,直到t>a[i]为止;
4)将t存入a[i+1](注意是i+1);
5)输出新的数列.
(注意:数组要保留足够的空间,即定义6个元素的整型数组).

#include <stdio.h>
int main()
{
    int a[6],i,t;
    printf("please input five numbers in order:\n");
    for(i=0;i<5;i++)
    {
        scanf("%d",&a[i]);
    }
    
    printf("please input the new number:\n");
    scanf("%d",&t);
    
    for(i=4;i>=0;i--)
    {
        if(t<a[i])
            a[i+1]=a[i];
		else break;
    }
    a[i+1]=t;
    
    printf("the new order is:\n");
    for(i=0;i<6;i++)
         printf("%d",a[i]);
    return 0;
}

4、输入5个数,将5个数中的素数按照与输入顺序相反的顺序输出.

#include <stdio.h>
int primer(int n);//自定义判断素数的函数

int main()
{
	int i,j,a[5],b[5]={0};
	printf("please input 5 numbers:\n");
	for(i=0;i<5;i++)
		scanf("%d",&a[i]);//依次输入五个数放入a数组

	for(i=0;i<5;i++)
	{
		if(primer(a[i])==1) b[i]=a[i];//将b数组对应a数组为素数的位置更换为a中的元素
	}

    for(j=4;j>=0;j--)
	{
		if(b[j]==0) continue;
		else printf("%-4d",b[j]);
	}//将b数组除0以外的数逆序输出

	return 0;
}

int primer(int n)
{
	int i;
	for(i=2;i<n;i++)
	    if(n%i==0)return 0;
	return 1;
}

5、青年歌手参加歌曲大奖赛,有十个评委给比赛的选手进行评分,编写一个程序,计算选手的最终得分.选手的最终得分是从十个评委评分中,去掉最高分,去掉最低分后计算的平均分.

程序设计思路提示
用一维数组a存储评委给选手的评分.
1)输入评委评分,存入数组a中;
2)利用循环语句,求出数组的和sum,并采用打擂法求出数组的最大值max和最小值min;
3)计算最终得分(sum-max-min)/8,并输出.

#include <stdio.h>
int main()
{
	int i,score[10],max,min,sum=0;
	double result;
	
	for(i=0;i<10;i++)
	    scanf("%d",&score[i]);
	max=score[0];
	min=score[0];

	for(i=1;i<10;i++)
	{
		if(score[i]>max)max=score[i];
	    if(score[i]<min)min=score[i];
	}

	for(i=0;i<10;i++)
		sum+=score[i];

	result=(sum-max-min)/8;
	printf("the final reslut is %lf",result);

	return 0;
}

6、程序从键盘读入若干整数(小于10个),对输入的数据进行从大到小排序,并将排序结果输出到屏幕上.要求采用的分别采用冒泡排序、插入排序和选择排序算法实现.

(1) 冒泡排序:
冒泡排序算法思想:从第一个元素开始,与相邻的后面的元素两两比较,若前一个数更小则互换位置,如此最小的数便在数组的最后;第二轮比较同理,可确定倒数第二小的数;以此类推.

#include <stdio.h>
void BubbleSort(int a[],int n);
int main()
{
	int s[10],n,i;
	printf("please input the number of numbers:\n");
	scanf("%d",&n);
	printf("please input %d numbers:\n",n);
	for(i=0;i<n;i++)
		scanf("%d",&s[i]);
	BubbleSort(s,n);
	
	for(i=0;i<n;i++)
		printf("%4d",s[i]);
	return 0;
}

void BubbleSort(int a[],int n)
{
	int i,j,temp;
	for(i=0;i<n-1;i++)
		for(j=0;j<n-1-i;j++)
			if(a[j]<a[j+1])
			{
				temp=a[j];
				a[j]=a[j+1];
				a[j+1]=temp;
			}
}

(2) 插入排序
插入排序算法思想:插入排序的基本操作就是将一个数据插入到已经排好序的有序数组中,从而得到一个新的、个数加1的有序数组。

void InsertSort(int a[],int n)
{
    int i,j,temp;
	for(i=1;i<n;i++)
	{
		temp=a[i]; /* 空出a[i]单元 */
		for(j=i-1;j>=0&&a[j]<temp;j--)
			a[j+1]=a[j];/* 小于temp的数向后移位 */
	    a[j+1]=temp; /* temp归位,注意循环之后再执行了一次j--,故此时temp插入位置为j+1 */ 
	}
}

(3) 选择排序
选择排序算法思想:从待排序的序列中,选择最小的一个记录下来,与第一个数据交换;然后从不包括第一个记录的序列中选择最小一个与第二个数据交换;如此重复,直至只剩一个数据为止。

void SelectSort(int a[],int n)
{
     int i,j,max,temp;
	 for(i=0;i<n-1;i++)
	 {
		 max=i; /*假设第一个数最大,记录其下标*/
		 for(j=i+1;j<n;j++)
             if(a[j]>a[max])
				 max=j;/*找最小数,将最小数的下标记录下来*/
		 if(max!=i)
		 {
			 temp=a[max];
			 a[max]=a[i];
			 a[i]=temp;
		 }/*将最小的数与第一个数进行交换*/
	 }
}

7、输入一个二维数组,找出二维数组中的所有最大值(可能有多个),及其所在的行号和列号(起始行,列为1)并输出行列号和对应数值。

#include <stdio.h>
int main()
{
	int matrix[3][3];
	int i,j,max_value;
	printf("please input a 3*3 matrix:\n");
	for(i=0;i<3;i++)
		for(j=0;j<3;j++)
			scanf("%d",&matrix[i][j]);

	max_value=matrix[0][0];
	for(i=0;i<3;i++)
		for(j=0;j<3;j++)
			if(matrix[i][j]>max_value)
				max_value=matrix[i][j];
	printf("the largest number is %d\n",max_value);

	for(i=0;i<3;i++)
		for(j=0;j<3;j++)
			if(matrix[i][j]==max_value)
				printf("在第%d行,第%d列\n",i+1,j+1);
	return 0;
}

8、函数功能:声明字符数组s;通过gets系统函数输入5进制数字字符串(注意是字符串且长度小于10);计算相应的整数;输出整数.

#include <stdio.h>
int main()
{
	char s[10];
	int i,x=0;
	gets(s);
	for(i=0; s[i]; i++)
		x=x*5+s[i]-'0';
	printf("%d\n",x);
	return 0;
}

9、已知二维字符数组name[5][10]保存了5个字符串,每个字符串的长度小于10.以下程序通过使用库函数strcmp、strcpy的字符串比较和复制实现按字典顺序对5个字符串排序;最终输出排序后的字符串.其中排序功能由sort函数实现.

#include <stdio.h>
#include <string.h>
void sort(char s[5][10]);
int main()
{
	char name[5][10]={"Mary","George","Andy","Tom","Iris"};
	int i;
	sort(name);
	
	for(i=0;i<5;i++)
		printf("%s\n",name[i]);
	return 0;
}

void sort(char s[][10])
{
	int i,j;
	char temp[10];
	for(i=0;i<4;i++)
		for(j=i+1;j<5;j++)
		if(strcmp(s[i],s[j])>0)
		{
			strcpy(temp,s[i]);
			strcpy(s[i],s[j]);
			strcpy(s[j],temp);
		}
}

10、编写程序,输入由数字字符构成的字符串,长度小于100,(若有空格,先去除空格),分别统计该字符串中数字字符对应的数字中奇数和偶数的个数。例如:

输入:7843028503
输出:4 6

#include <stdio.h>
#include <string.h>
int main()
{
	int a[100],i,k,n,o,j;//o代表偶数,j代表奇数
	char str[100];
	o=0;
	j=0;
	gets(str);
	n=strlen(str);
	for(i=0,k=0;i<n;i++)
	{
		if(str[i]!=32)
		{
		   a[k++]=str[i]-48;
		}
	}
	
	for(i=0;i<k;i++)
	{
		if(a[i]%2==0)
			o=o+1;
		else
			j=j+1;
    }
	printf("%d,%d\n",j,o);
    return 0; 
}

11、编写程序,输入字符串(不包含空格),删除字符串中ASCII码值能被3整除的字符,将剩余字符按从小到大排序后输出.

#include<stdio.h>
#include<string.h>
int main()
{
	char str[100];
	int n,i,j,t;
    gets(str);
    n=strlen(str);
    for(j=0;j<n-1;j++)//冒泡排序
	{
		for(i=0;i<n-1-j;i++)
          if(str[i]>str[i+1])
		  {
			  t=str[i];
			  str[i]=str[i+1];
			  str[i+1]=t;
		  }
	}
    for(i=0;i<n;i++)
	{
		if(str[i]%3==0)
            continue;
        else
            printf("%c",str[i]);
	}
    return 0;
}

12、编写一个程序,判断一个字符串是否是回文字符串.所谓回文字符串就是正读和反读都一样的字符串.例如,"asouluosa"是一个回文字符串.

程序设计思路提示:用一维字符数组str字符串.依次比较数组两端的元素是否相同:对字符串中第一个位置的字符与最后一个字符进行比较,如果相同,则进行第二个位置字符与倒数第二个位置的字符进行比较,……,依次类推,如果其中一旦存在不相等的情况,则不是回文串,如果测试完所有字符都相等,则说明是回文串.

#include<stdio.h>
#include<string.h>
int main()
{
	char str[20];
	int i,length,k;
	int flag=0;
	gets(str);
	length=strlen(str);
	k=strlen(str)/2;

	for(i=0;i<k;i++)
		if(str[i]!=str[length-1-i])
	    {
			flag=1;
			break;
		}

	if(flag==0)printf("Yes");
	else printf("No");
	return 0;
}
  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值