数组的介绍

目录

一、一维数组

1.一维数组的创建

2.一维数组的初始化

3.一维数组在内存中的存储方式

 4.一维数组的数组名问题

 二、二维数组

1.二维数组的初始化

 2.二维数组的存储方式

 三、数组下标越界问题

四、习题: 写一个冒泡排序

五、数组名问题


一、一维数组

1.一维数组的创建

数组的创建方式:type_t  arr_name [const_n]

type_t 是指数组的元素类型 const_n 是一个常量表达式,用来指定数组的大小

下面通过代码来介绍数组的创建以及创建时所要注意的问题

int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };   //如果将其换成变量的形式
	const int n = 10;   //所以,如果不支持的话 ,用const也不能,因为在C语言里面const定义的是 长变量 也是一个变量
	                    //但是在c++里面的话 const定义的是一个常量 跟C语言完全不一样 因此c++可以             
	 
	scanf("%d", &n);//通过n来改变数组的大小  
	int arr[n]; //c99引入了变长数组(长度可变)的概念,允许数组的大小用变量来指定,如果编译器不支持c99中的变长数组,那就不能使用
		//所以vs2022是不支持变长数组的
	return 0;
}

2.一维数组的初始化

数组的初始化是指在创建数组的时候给数组赋一些值

不同类型的数组有不同类型的创建方式

具体的代码演示:

int arr[10] = { 1,2,3,4 };//指的是不完全初始化 ,指初始化了一部分,剩下的默认为0;
	char arr1[] = { 'a','b','c' };
	char arr2[] = { 'a',98,'c' };  // arr1[] arr2[] 其实是一样的 98对应的ASCII值就是98
	//对数组进行初始化的时候 []里面的值是可以不用写的 这时候初始化的大小跟你赋的值的内容来定
	char arr3[] = "abc";//这种数组的创建是有\0的,且不完全初始化的值剩余的是默认为 \0

当不初始化的时候,编译器会有自己默认规则

1.当不初始化的时候打印,系统会随机赋值。

2.全局变量跟静态变量的默认初始值均为0。

因为全局变量跟静态变量都是在内存的静态区里面创建的,这里面创建的值默认初始值为零 ,但是在栈区里面创建的值 如:局部变量和形式参数

下面通过代码来具体实现一维数组的输入与输出

#define  _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
int main()
{
	int	arr4[10];
	//下标           0 1 2 3 4 5 
	//写一个代码赋值1~10
	int sz = sizeof(arr) / sizeof(arr[0]);
	 int i = 0;

	//赋值
	for (i = 0; i < sz; i++)
	{
		//arr4[i] = i + 1; //打印1~10

		scanf("%d", &arr4[i]); //输入并输出

        //或者使用
       // scanf("%d", arr4+i); //输入并输出 这样就不需要&了
	}
	//打印
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr4[i]);
	}
	//printf("%d\n", arr4[4]);//[]下标引用操作符,[]有两个操作数:arr,4
	return 0;
}

3.一维数组在内存中的存储方式

一维数组在内存当中是连续存放的,随着数组下标的增长,地址是由低到高变化的

 下面通过一串代码的运行来具体介绍

#define  _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	//打印数组的每个元素的地址
	int sz = sizeof(arr) / sizeof(arr[0]);
	int i = 0;
	int* p = &arr[0];
	for (i = 0; i < sz; i++)
	{
		printf("arr[%d] = %p <====> %p\n", i, &arr[i],p+i);  //p+1 是跳过一个整型 即跳过4个字节
		//%p - 打印地址(16进制)
		//%d - 打印整数(10进制)
	}

	//arr  数组名是指第一个元素的地址
	return 0;
}

 4.一维数组的数组名问题

 二、二维数组

二维数组的创建与一维数组相差不大,具体通过下面的代码来具体介绍

1.二维数组的初始化

    int arr[3][5]; //三行五列
	int arr1[3][5] = { 1,2,3,4,5,6 }; //初始化1   不完全初始化  
	//int arr1[][5] = { 1,2,3,4,5,6 }; //初始化1   不完全初始化  
	//int arr1[3][] = { 1,2,3,4,5,6 }; //初始化1   不完全初始化    报错
	// 
	//总结:行可以省略,但列不可以省略 
	int arr2[3][5] = { {1,2 }, {3, 4}, {5, 6} };//初始化2
	//第一行1,2,0,0,0
	//第二行3,4,0,0,0
	//第三行5,6,0,0,0

 通过代码来演示二维数组的输入与输出

#define  _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
	int arr3[3][5] = { {1,2 }, {3, 4}, {5, 6} };
	int i = 0;
	for (i = 0; i < 3; i++) //第i行
	{
		int j = 0;
		for (j = 0; j < 5; j++) //第j列
		{
			printf("%d ", arr3[i][j]);
		}
		printf("\n");
	}
return 0;
}

当然这里面的3,5也可以用sizeof来写

#define  _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main(){
    int i = 0;
	for (i = 0; i < sizeof(arr)/sizeof(arr[0]); i++) //第i行   解释:将arr全部除以第一行全部arr[0] 即为行数
	{
		int j = 0;
		for (j = 0; j < sizeof(arr[0])/sizeof(arr[0][0]); j++) //第j列  解释: 将arr[0]的一行的全部除以第一个元素arr[0][0]即为行数的大小
		{
			printf("%d ", arr3[i][j]);
		}
		printf("\n");
	}
   return 0;
}

 2.二维数组的存储方式

二维数组:在内存当中也是连续存放的,是一行一行放的
二维数组可以理解为一维数组的数组

 通过代码演示介绍二维数组的存储方式

#include<stdio.h>
int main(){
int i = 0;
	int* p = &arr3[0][0];
	for (i = 0; i < sizeof(arr3) / sizeof(arr3[0]); i++) 
	{
		int j = 0;
		for (j = 0; j < sizeof(arr3[0]) / sizeof(arr3[0][0]); j++) 
		{
			printf("&arr3[%d][%d] = %p\n ",i,j ,&arr3[i][j]);
		}
		printf("\n");
	}

	return 0;
}

 

 三、数组下标越界问题

数组下标是有范围限制的,数组规定是从0开始的,如果数组有n个元素,那么最后一个数组元素的下标为n-1。

所以数组的下标小于0或者大于n-1,就是数组的越界访问了,超出数组的合法空间的访问。

四、习题: 写一个冒泡排序

代码:

void bubble_sort(int arr[],int sz)//arrp[]本质上是一个指针  也可以将其写成void bubble_sort(int* arr,int sz)
{
//	int sz = sizeof(arr) / sizeof(arr[0]);    //原因在这里 这里面传入过去数组之后,sz计算的大小为2
	                                            //原因就是数组名的问题
	
	//趟数
	int i = 0;
	for (i = 0; i < sz - 1; i++)
	{
		int flag = 1;//假设已经有序
		//每一趟冒泡排序的一个过程
		int j = 0;
		for (j = 0; j <sz-1-i ; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				flag = 0; 
				//交换
				int tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
			}
			if (flag == 1)
			{
				break;//当排完第一趟的时候发现flag没有变,则说明是一个有序数列
			}
		}
	}
}
int main()
{
	int arr[] = { 9,8,7,6,5,4,3,2,1,0 };
	//写一个冒泡排序算法的函数,用来排序arr数组的内容
	//bubble_sort(arr);
	int sz = sizeof(arr) / sizeof(arr[0]);
	//解决问题  把sz在主函数中定义 并且传到数组当中
	bubble_sort(arr,sz); //数组在传参的时候一般都是传数组名 
	int i = 0;
	//int sz = sizeof(arr) / sizeof(arr[0]);      //但是这样的代码运行是有问题的 
	                                            //原因是在函数内部
	for (i = 0; i < sz; i++)
	{
		printf("%d ",  arr[i]);
	}
	return 0;
}

实现原理图:

通过上述代码具体引入了数组名的问题

五、数组名问题

绝大多数数组名就是数组首个元素的地址

有两个例外:

1. sizeof(数组名),数组名不是数组首个元素的地址,数组名表示整个数组 ,计算的是整个数组的地址

2. &数组名,数组名不是数组首个元素的地址,数组名表示的是整个数组,取出的是整个数组的地址

代码演示: 

#include<stdio.h>
int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	printf("%p\n", arr);
	printf("%p\n", arr+1);

	printf("%p\n", &arr[0]);
	printf("%p\n", &arr[0]+1);

	printf("%p\n", &arr);
	printf("%p\n", &arr+1);

	printf("%d \n", sizeof(arr));
	return 0;
}

代码图解:

 

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值