数组——C语言(笔记)

数组

在这里插入图片描述

1. 一维数组的定义及使用:

1) 一维数组的定义方式为:
<类型说明符> <数组名>[<常量表达式>];

在这里插入图片描述

其中:常量表达式表示数组中元素的个数,称为数组长度。== 常量表达式的值必须为整数且大于等于1==。
注意:数组一经定义,数组长度就保持不变。为了方便修改数组大小,可以使用宏常量和const常变量。

eg.  #define N 10            int arr1[N];
const M=20;            char arr2[M];

一维数组的特点:
1、数据类型相同
2、在内存中占据一片连续的存储区(C语言规定数组元素是连续存放的)
在这里插入图片描述

2) 一维数组的引用:

数组元素的表示形式为:

数组名[<下标>]//(下标从0开始)

<下标>可以是整型常量或整型表达式。== array[8]、array[2*3]、array[i](i为整型变量)均是合法的引用==,但引用时不能超出下标的最大值。

3) 数组初始化:

(1)在定义数组时对数组全部元素赋初值。例如:

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

(2)可以给一部分元素赋初值。例如:

 int array[10]={0, 1, 2, 3};

相当于:

 int array[10]={0, 1, 2, 3000000}; 

(3)如果想使一个数组中全部元素值为0,可以写成:
int array[10]={0, 0, 0, 0, 0, 0, 0, 0, 0, 0};int array[10]={0};
(4)在给全部数组元素赋初值时,可以不指定数组长度。例如:
int array[ ]={0, 1, 2, 3, 4}; 相当于: int array[5]={0, 1, 2, 3, 4};
(5)如果定义数组时将存储类别定义为局部静态的或全局的,则C编译器自动地将所有数组元素的初值置为0。如果存储类别定义为局部动态的数组元素为不确定值

static int A[10];//默认各元素的值为0;
int A[10];//各元素的值为随机数

注意:
i. 当数组在全局变量区定义时,默认初值为0。
当数组在局部变量区定义时,如果不写“ { } ”,则默认的初值为乱码
当数组在局部变量区定义时,如果写“ { } ”或给某几位赋值时,则其他未赋值的数默认初值为0。
ii. 数组必须先定义后使用, 且只能逐个引用数组元素的值而不能一次引用整个数组全部元素的值 。
iii. 整个数组不允许进行赋值运算、 算术运算等操作, 只有元素才可以。

4) 获取数组中元素的个数

一维数组数组名的用途:
可以统计整个数组在内存中的长度
数组所占内存:sizeof(arr)
每个元素所占内存:sizeof(arr[0])——获得数组中元素的个数:sizeof(arr)/sizeof(arr[0])

2. 一维数组作函数参数:

i. 一维数组元素作函数参数

与用普通单个变量做实参一样,单向值传递,每次只传递一个元素(一个变量的值)

ii. 一维数组名作函数参数

实参与形参均用数组名(此时数组名作为数组的起始地址传递)。
实参和形参可用指针(ch9介绍)
数组名是数组的起始地址数组名作函数实参时,是把实参数组的起始地址(“起始地址”也称为“首地址”)传递给形参

实参数组和形参数组共用存储单元。

iii. 排序法
(一) 冒泡法

在这里插入图片描述
在这里插入图片描述

void bubble_sort(int a[],int n)
	{//冒泡排序法的核心
		int i,j,t;
		for(j=0;j<n-1;j++)
		{
			for(i=0;i<n-1-j;i++)
			{
				if (a[i]>a[i+1])
				{
					t=a[i];
					a[i]=a[i+1];
					a[i+1]=t;
				}}}}

缺点:效率低下

(二) 选择法

选择法的思想:第1趟扫描,将a[0]到a[5]中最小数的下标找到,设为p,若 p!=0,则a[0]与a[p]交换位置;第2趟扫描,将a[1]到a[5]中最小数的下标找到,设为p,若 p!=1,则a[1]与a[p]交换位置……依此类推,每扫描一次找出一个未经排序的数中最小的一个,共需5次扫描,第i次扫描时(i=0~4),扫描范围的第1个元素的下标为 i,最后一个元素的下标为 5。
在这里插入图片描述

void select_sort(int a[],int n)
{
	int i,j,p,t;
	for(i=0;i<n-1;i++)
	{
		p=i;
		for(j=i+1;j<n;j++)
			if(a[j]<a[p]) p=j;
		if(p!=i)
		{
			t=a[p];
			a[p]=a[i];
			a[i]=t;
		}}}

冒泡排序
优点: 比较简单,空间复杂度较低,是稳定的;
缺点: 时间复杂度太高,交换次数多,效率慢;<=n*(n-1)/2
选择排序
优点:一轮比较只需要换一次位置,交换次数少;<=n-1
缺点:效率慢,不稳定。

(三) 插入法排序
后插算法

设数组有N个元素,第i次循环结束后,数组前i个元素排成升序,即有a[0]≤a[1]≤…≤a[i-1]。现在要将a[i]元素插入,使前i+1个元素保持升序。首先将a[i]送p,然后将p依次与a[i-1], a[i-2], …, a[0]进行比较,将比p大的元素依次右移一个位置,直到发现某个j(0≤j≤i-1),有a[j]≤p成立,则将p赋值给a[j+1];如果不存在这样的a[j],那么在比较过程中,a[i-1], a[i-2], …, a[0]都依次右移一个位置,此时将p赋值给a[0]。

void ba_ins_sort(int a[],int n)
{
	int i,j,p;
	for(i=1;i<n;i++)
	{
		p=a[i];
		for(j=i-1;j>=0&&p<a[j];j--)
			a[j+1]=a[j];
		a[j+1]=p;
	}}
前插算法

设数组有N个元素,第i次循环结束后,数组前i个元素排成升序,即有a[0]≤a[1]≤…≤a[i-1]。现在要将a[i]元素插入,使前i+1个元素保持升序。首先将a[i]送p,然后将p依次与a[0], a[1], …, a[i-1]进行比较,直到发现某个j(0≤j≤i-1),有a[j]>p成立,则把a[j], a[j+1], …, a[i-1]依次右移一个位置,使得a[j]=p。

void ah_ins_sort(int a[],int n)
{
	int i,j,k,p;
	for (i=1;i<n;i++)
	{
		p=a[i];
		for (j=0;j<i&&p>=a[j];j++);
		for(k=i;k>j;k--)
			a[k]=a[k-1];
		a[j]=p;
	}
}

(四)筛选法
#include <stdio.h>//筛选法求100内素数
#define N 100

void prime(int a[],int n)
{
	int i,j;
	for(i=1;i<n-1;i++)
		for(j=i+1;j<n;j++)
			if(a[i]!=0&&a[j]!=0&&a[j]%a[i]==0)
				a[j]=0;
}
int main()
{
	int a[N],i,n;
	for (i=0;i<N;i++)
		a[i]=i+1;
	prime(a,N);
	printf("Prime:1~100:\n");
	for(i=1,n=0;i<N;i++)
	{
		if(a[i]!=0)
		{
			printf("%d\t",a[i]);
			n++;
			if(n%5==0)
				printf("\n");
		}}
        printf("\n");
		return 0;
}
(五) 顺序查找
int search(int a[],int x,int n)
{//顺序查找,x=预查找的数,n=元素个数
	int i;
	for(i=0;i<n;i++)
		if(x==a[i])
			return i;
	return -1;//笑死根本找不到
}

(六) 折半查找法

前提:数组中的值按递增次序排好序。

#include <stdio.h>//折半查找
#define M 10
int bi_search(int a[],int x,int n)
{//二分查找,x=预查找数,n=元素个数
	int low=0,mid,up=n-1;//左右两部分
	while (low<=up)
	{
		mid=(low+up)/2;
		if(x==a[mid])
			return mid;//正好找到
		else if(x<a[mid])//左半部分
			up=mid-1;
		     else //右半部分
				 low=mid+1;
	}
	return -1;//笑死根本找不到
}

3. 多维数组的定义和使用

(一) 二维数组

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

<类型说明符> <数组名>[<常量表达式1>][<常量表达式2>];

在这里插入图片描述

在这里插入图片描述

引用二维数组元素的形式为:

数组名[<下标1>][<下标2>]

下标必须是整型表达式,如下是合法的引用:

  a[1][2], a[2 - 1][2*2 - 1], a[i - 1][2*j](i、j 为整型变量)

存储
在这里插入图片描述
在这里插入图片描述

(二) 二维数组的初始化
i.	int  a[4][3]={ {1, 2, 3},  {4, 5, 6},  {7, 8, 9},  {10, 11, 12} } ; //按行初始化 ,四行三列
ii.	int  a[4][3]={ 1, 2, 3,  4, 5, 6, 7, 8, 9, 10, 11, 12 };
iii.	int  a[4][3]={ {1},  {4},  {7},  {10} };//同一个{}中为同一行,对部分元素赋初值,给每一行的第一个元素赋值,其余为零

注意:
1.初值列表提供的元素个数不能超过数组长度, 但可以小于数组长度。
2.如果初值个数小于数组长度, 则只初始化前面的数组元素; 剩余元素初始化为0。
3.int a[ ][4]={1,2,3,4,5,6,7,8,9,10,11,12};根据给定的初始化数据,自动确定数组的行数

其中第一维的长度可不指定,第二维的长度不能省

4. 字符数组

  1. 用来存放字符型数据的数组称为字符数组,其元素是一个个的字符。
    字符数组的定义形式为:
char 字符数组名[常量表达式],......;

例如:

char s[20]; //定义字符数组
char s[4]={'J','a','v','a'}; //字符数组初始化

注意:C语言规定字符串是以‘\0’(ASCII值为0)字符作为结束符的字符数组。在程序中可以通过判断数组元素是否为空字符来判断字符串是否结束,换言之,只要遇到数组元素是空字符,就表示字符串在此位置上结束。由于字符串实际存放在字符数组中,所以定义字符数组时数组的长度至少为字符串长度加1(空字符也要占位)

在这里插入图片描述
在这里插入图片描述
注意:
初值个数>数组长度:出错
初值个数<数组长度:其余元素自动定为空字符(数值为0或ASCII为0,即’ \0 ')
初值个数=数组长度:定义时可省略数组长度
在这里插入图片描述

2) 字符数组的输入与输出:

在这里插入图片描述
注意scanf(“%s”,str1);不能输入带空格的字符串
因为 %s 会在遇到空格、制表符或换行符时停止读取。

在这里插入图片描述
想要输入带空格的字符串,可以使用 fgets() 或者 gets() 函数。但是,由于 gets() 函数不检查输入的字符串长度,因此可能会导致缓冲区溢出和安全漏洞。因此,建议使用 fgets() 函数来读取带空格的字符串。例如:

fgets(str1, sizeof(str1), stdin);

gets函数是C语言中的一个输入函数,用于从文件或标准输入流中读取一行字符串。它的原型如下:

char *fgets(char *str, int n, FILE *stream);

其中,str是一个指向字符数组的指针,用于存储读取的字符串;n是一个整数,表示要读取的最大字符数;stream是一个指向FILE类型的指针,表示要读取的文件或标准输入流。
fgets函数会读取指定的文件或标准输入流中的一行字符串,并将其存储到str指向的字符数组中,直到读取到换行符或读取的字符数达到n-1为止。如果读取成功,fgets函数会返回str指针;否则,它会返回NULL。
fgets函数的优点是可以避免缓冲区溢出的问题,因为它会自动将读取的字符串截断为n-1个字符,以确保不会超出指定的字符数。同时,它也可以读取包含空格在内的字符串,因为它会将空格作为普通字符读取。

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

5. 字符串处理函数

C编译系统提供的字符串处理函数在string.h头文件中作了说明,要调用字符串处理函数时,需要包含string.h文件。

1) 求字符串长度函数strlen(字符串)

函数原型:int strlen(char s[ ] )
strlen是英文STRing LENgth(字符串长度)的缩写
功能:求字符串的长度,即字符串中有效字符的个数。

2) 字符串拷贝函数strcpy(字符数组1, 字符串2)
   函数原型:`char * strcpy (char s1[ ], char s2[ ])` 
    strcpy是英文STRing COPY的缩写
    功能:将字符串s  2拷贝到字符数组s1中去。如果粘贴函数原来已有数据,那么会被新的数据覆盖掉。
3) 字符串连接函数:strcat(字符数组1, 字符数组2)
    函数原型:`char * strcat (char s1[ ], char s2[ ])`
    strcat是英文STRING CATENATE的缩写。
    功能:把字符数组s2中的字符串连接到字符数组s1中字符串的后面,对字符数组s2中的内容没有变化。
4) 字符串比较函数:strcmp(字符串1, 字符串2)
   函数原型:`int strcmp (char s1[ ], char s2[ ])` 
    strcmp是英文STRING CoMPARE的缩写。
    功能:用来比较两个字符串是否相等。
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值