C语言学习笔记——数组

数组

一、数组的概念

数组是一组相同类型元素的集合 分为一维数组和多为数组,多维数组常见的是二维数组。

1、数组中存放的是一个或多个数据,但是数组元素个数不能为0.

2、数组中存放的多个数据,类型是相同的。

二、数组的创建和初始化

1、一维数组:type arr_name[常量值];

①不初始化

int arr1[10];		char arr2[8]

②完全初始化

int arr[5]={1,2,3,4,5}		//{}内元素个数等于数组长度

③不完全初始化

int arr[5]={1,2,3}		//{}内元素个数小于数组长度,未初始化部分默认值是0

④不指定长度,通过大括号内元素个数确定数组长度

int arr[]={1,2,3,4}		//数组如果初始化了,	[]内可以省略长度,编译器根据{}的内容长度确定数组的长度

错误的初始化

int arr[5]={1,2,3,4,5,6}	//{}内的元素个数大于[]定义的数组长度
2、数组的类型

数组也是有类型的,算是一种自定义类型,去掉数组名留下的就是数组的类型

如:

int arr1[4];
int arr2[5];
cahr ch[6];

arr 1的数组类型是 int [4]

arr 2的数组类型是 int [5]

ch的数组类型是 char [6]

四、一维数组的使用

1数组下标

C语言规定数组是有下标的,下标从 0 开始,假设数组有n个元素,最后一个元素的下标是 n-1 ,下标就相当于数组元素的编号

如下:

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

image-20231105230713858

在c语言中数组的访问提供了一个操作符 [ ] ,这个操作符叫下标引用操作符

比如要访问下标为7的元素,就可以使用 arr[7],想要访问下标为3的元素,就可以使用 arr[3]

2、数组元素的打印(遍历)

使用for循环产生0~9的下标,用下标访问打印

#include <stdio.h>

int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);
	}
}

image-20231102225140509

3、使用for循环依次向数组中输入数据
#include <stdio.h>

int main()
{
	int arr[10];
	for (int i = 0; i < 10; i++)
	{
		scanf("%d", &arr[i]);
	}
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);
	}
}

image-20231102225508220

4、一维数组在内存中的存储

打印数组元素的地址 %p用于打印地址

#include <stdio.h>

int main()
{
	int arr[10] = { 0 };
	for (int i = 0; i < 10; i++)
	{
		printf("%p\n", &arr[i]);
	}
}

image-20231102230217424

从输出结果分析,数组随着下标的增长,地址越来越大,且每两个相邻地址差为4(因为一个整型占用4个字节)

所以:数组在内存中是连续存放的

5、sizeof计算数组元素个数

在遍历数组的时候,往往需要知道数组元素的个数,这时可以使用sizeof(计算类型或变量大小,返回其占用的字节数)

int main()
{
	int arr[10] = { 0 };
	int len = sizeof(arr) / sizeof(arr[0]);		//用整个数组的大小(字节)/单个数组元素的大小(字节)
	printf("%d", len);
}

image-20231102230723513

五、二维数组

1、二维数组的概念

如果把以为数组作为数组的元素,就是二维数组,二维数组作为数组的元素,就是三位数组,二维及以上的数组成为多维数组

image-20231103222934419

2、二维数组的创建 type arr_name[常量1] [常量2]
int arr[3][5]		
double [2][8]		

[3]可以看作行,[5]可以看作列 3行5列

[2]可以看作行,[8]可以看作列 2行8列

六、二维数组的使用

1、二维数组初始化

①不完全初始化

int arr1[3][5]={1,2};	int arr2[3][5]={0}

image-20231103223836990

int arr[3][5]={1,2,3,4,5,6,7};	//依次初始化每一行,剩余不够的默认为0

②完全初始化

int arr[3][5]={1,2,3,4,5 2,3,4,5,6, 3,4,5,6,7};		

③按照行初始化

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

{}内就是一行,该行剩余元素默认为0

④行可以省略

int arr[][5]={1,2,3,4,5,6,7};

可以不指定多少行,但一定要指定多少列,否则不知道多少列后到下一行

看一下这几种的结果

int arr5[][5]={1,2,3};
int arr6[][5]={1,2,3,4,5,6,7};
int arr7[][5]={{1,2},{3,4},{5,6}};

image-20231103224958997

2、二维数组的下标

二维数组的访问也使用下标形式,二维数组具有行和列,只要锁定了行和列就能唯一确定数组中的一个元素,也是0开始

int arr[3][5]={1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7};

image-20231103225214076

绿色为行号,蓝色为列号,比如第2行,第4列,arr[2] [4] 就能快速定位到 7

#include <stdio.h>
int main()
{
	int arr[][5] = { 1,2,3,4,5,2,3,4,5,6,3,4,5,6,7 };
	printf("%d", arr[2][4]);
	return 0;
}

image-20231103225727994

3、使用for循环嵌套一次往数组中赋值和遍历
int main()
{
	int arr[3][5] = {0};
	for (int i = 0; i < 3; i++)		//i控制行号
	{
		for (int j = 0; j < 5; j++)		//j控制列号
		{
			scanf("%d", &arr[i][j]);	//向第i行j列赋值
		}
	}
	
	for (int i = 0; i < 3; i++)		//i控制行号
	{
		for (int j = 0; j < 5; j++)		//j控制列号
		{
			printf("%d ", arr[i][j]);		//打印第i行j列的元素
		}
		printf("\n");		//打印完一列后换行
	}
}

image-20231105230651900

也可以将输入和打印写到同一个循环中

#include <stdio.h>

int main()
{
	int arr[3][5] = { 0 };
	int i = 0;
	for (i = 0; i < 3; i++)		//i控制行号
	{	
		int j = 0;
		for (j = 0; j < 5; j++)		//j控制列号
		{
			scanf("%d", &arr[i][j]);	//向第i行j列赋值
			printf("%d ", arr[i][j]);	//打印
		}
	}
	return 0;
}

上一种方法,必须将全部元素初始化后一块打印,而输入和打印写进同一个循环,可以边打印遍输出,每次输入几个就打印几个

4、二维数组在内存中的存储
#include <stdio.h>

int main()
{
	int arr[3][5] = { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 };
	for (int i = 0; i < 3; i++)		//i控制行号
	{

		for (int j = 0; j < 5; j++)		//j控制列号
		{
			printf("&arr[i][j]=%p\n",&arr[i][j]);
		}
	}
	return 0;
}

image-20231105221420801

二维数组在内存中也是连续存放的!!!,存完一行,到下一行的差也是4个字节(int)

image-20231105221744802

七、C99标准

C99标准之前,数组的大小是由常量指定的。

C99标准之后,引入了变长数组的概念,可以用变量来指定数组的大小。

VS默认不支持C99中的变长数组,可以使用小熊猫DevC++来测试,它自带gcc编译器,支持C99之后的变长数组。

变长数组

变长数组的根本特性,就是数组长度只有在运行时才能确定,所以,变长数组不能初始化。他的好处是程序员不必在开发时,随意为数组指定一个估计的长度,程序可以在运行时为数组分配精确的长度。

迷惑点:变长数组的意思是数组的大小可以用变量来指定,在程序运行的时候,根据变量的大小来指定数组元素的个数,而不是说数组的大小是可变的。

因为,数组的大小一旦确定就不能再变化了

练习

1、字符从两端向中间逐个显示
#include <stdio.h>
#include <string.h>
#include <windows.h>
#include <stdlib.h>
int main(){
	char arr1[]="welcome to bit";	//[welcome to bit\0]
	char arr2[]="##############";
	int left = 0;	//第一个元素下标 
	int right = strlen(arr1)-1; 	//找到末尾元素下标,数组是char,可以直接用strlen计算长度,一个字符就是一个元素
	while(left<=right){
		arr2[left] = arr1[left];
		arr2[right] = arr1[right];
		printf("%s\n",arr2);
		Sleep(1000);	//等待1000毫秒 Sleep的头文件	windows.h
		system("cls");	   //清除屏幕,使打印结果始终在第一行	sys的头文件		stdib.h
		left++;
		right--;
	} 
	printf("%s",arr1);	//循环的最后cls清屏了,这里再打印一次
//	return 0;
}

image-20231105225142451

2、二分查找
int main(){
	int arr[]={1,2,3,4,5,6,7,8,9,10,11};
	int k= 11;
	int sz= sizeof(arr)/sizeof(arr[0]);	//计算数组个数
	int left= 0;	//左边下标	
	int right= sz- 1;	//右边下标
	//二分查找法 
	while(left<=right){
		int mid= (left+ right)/ 2;	//计算出中间下标
		if(arr[mid]> k)		//如果在数组左半边
			right= mid-1;	//将中间下标左移并赋值给右边下标,这里一定要减1,否则会进入死循环
		else if(arr[mid]< k)	//如果在数组右半边
			left= mid+1;	//将中间小标右移并赋值给嘴边下标,这里一定要加1,否则会进入死循环
		else{
			printf("找到了,下标是%d",mid);
			break;
	    } 	
	}
	if(left>right)
		printf("找不到"); 
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值