简单点_c_lesson11(数组)

1.数组定义

1.遍历数组
2.char[]作为字符输出和字符串输出,输入的区别
3.数组内存空间:数组的空间是在对应函数的栈帧内部空间开辟的。也就是所谓的栈上开辟空间。

1.1 遍历数组

#if 1
#include <stdio.h>
#include <windows.h>

int main()
{
	int arr1[] = {1,2,3};
	int arr[10] = {1,2,3};

	//求数组元素的个数
	int num = sizeof(arr1)/sizeof(arr1[0]);
	int i = 0;
	for(;i<num;i++){
		printf("%d ",arr1[i]);
	}
	printf("\n");

	for(i=0;i<10;i++){
		printf("%d ",arr[i]);
	}
	printf("\n");
	system("pause");
	return 0;
}
#endif

在这里插入图片描述

1.2 char[]:被当做普通的char数组,就跟int[]数组类似,需要遍历数组,下标访问的方式才能获取每一个元素。

#if 1
#include <stdio.h>
#include <windows.h>

int main()
{
	char arr[] = {'a','b','c'};
	int num = sizeof(arr)/sizeof(arr[0]);
	int i = 0;
	for(;i<num;i++){
		printf("%c = %d ",arr[i],arr[i]);
	}
	printf("\n");

	system("pause");
	return 0;
}
#endif

在这里插入图片描述

1.3 char[]:被整体当做字符串使用

#if 1
#include <stdio.h>
#include <windows.h>

int main()
{
	char arr[] = {'a','b','c','\0'};//如果有\0,就当做字符串处理。
	char arr1[] =  "asdfg";

	//打印方式:1.直接%s输出;2.遍历打印
	printf("%s\n",arr);
	printf("%s\n",arr1);

	/*int num = sizeof(arr)/sizeof(arr[0]);
	int i = 0;
	for(;i<num;i++){
		printf("%c ",arr[i]);
	}
	printf("\n");*/

	system("pause");
	return 0;
}
#endif

在这里插入图片描述

1.4 char[]:输入的区别

#if 1
#include <stdio.h>
#include <windows.h>

int main()
{
	char arr[] = {'a','b','c','\0'};//如果有\0,就当做字符串处理。
	char arr1[] =  "asdfg";

	//打印方式:1.直接%s输出;2.遍历打印
	printf("%s\n",arr);
	printf("%s\n",arr1);

	/*int num = sizeof(arr)/sizeof(arr[0]);
	int i = 0;
	for(;i<num;i++){
		printf("%c ",arr[i]);
	}
	printf("\n");*/

	system("pause");
	return 0;
}
#endif

在这里插入图片描述

2.一维数组

1.操作符: [] ,下标引用操作符,数组访问的操作符.
2.初始化一维数组,计算一维数组的元素个数,遍历输入和打印一维数组。
	int size = sizeof(arr)/sizeof(arr[0])
3.数组下表元素对应的空间、内容的理解--数组任意一个元素满足左值和右值问题
4.一维数组在内存中的存储
 (1)输出的是最小的地址
 (2)遍历数组元素时,打印的都是数组元素第一个字节的地址,物理空间是连续的。
 (3)数组名+1,就是下一个元素的第一个字节的地址。
	eg:int arr[10];arr是数组首元素的地址,arr+1就是第二个数组元素的第一个字节的地址。
 (4)数组只能整体初始化,不能整体赋值
 (5)数组是整体空间分布的,局部地址是依次增大的,但是把数组不要看成一个个独立个体去开辟空间,数组是整体开辟空间,
      所以在栈上把空间一次性开辟了。然后把最低地址作为零号下标a[0].6)定义一个全局变量数组,其不是在栈上开辟空间,而是在已初始化全局变量区。
 (7)不管是栈上还是已初始化全局变量区,数组开辟空间都是整体开辟空间,局部地址是依次增大的。
 总结:
	1.一维数组:a[0]...a[9]
	  地址依次增大,a[0]的地址最小;
	  一个变量中,第一个字节的地址,代表该变量的地址;
	2.地址是跨字节连续的;int--4char---1double---8
	3.对地址加1,其实就是加所选类型的大小;int arr[10];arr+1;
	4.数组只能对整体初始化,不能对整体赋值;
	5.数组整体空间分布,数组局部地址依次增大,栈上地址依次减小。

2.1 初始化一维数组,计算一维数组的元素个数,遍历输入和打印一维数组。

#if 1
#include <stdio.h>
#include <windows.h>

int main()
{   
	//数组的不完全初始化
	int arr[10] = {0};
	//计算数组的元素个数
	int sz = sizeof(arr)/sizeof(arr[0]);
	//对数组内容赋值,数组是使用下标来访问的,下标从0开始。

	int i = 0;//做下标
	//输入数组的内容
	for(i=0; i<sz; i++)
	{
		arr[i] = i;
	}
	//输出数组的内容
	for(i=0; i<sz; ++i)
	{
		printf("%d ", arr[i]);
	}
	system("pause");
	return 0;
}
#endif

在这里插入图片描述

2.2 数组下表元素对应的空间、内容的理解–数组任意一个元素满足左值和右值问题

#if 1
#include <stdio.h>
#include <windows.h>

int main()
{   
	//code1:
	//int arr[] = {11,22,33,44,55};
	//arr[1] = 1;//arr[1]:1号下标元素对应的空间
	//int a = arr[2];//arr[2]:2号下标元素对应的内容
	//printf("%d %d\n",arr[1],arr[2]);

	//code2:
	int arr[] = {11,22,33,44,55};
	scanf("%d",&arr[2]);//arr[2]的空间
	printf("%d",arr[2]);//arr[2]的内容
	system("pause");
	return 0;
}
#endif

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

2.3 一维数组在内存中的存储

#if 1
#include <stdio.h>
#include <windows.h>

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

int main()
{   
	//code1:
	/*int a = 0x11223344;
	printf("%p ",&a);*/

	//code2:地址是跨字节连续的
	/*//int arr[10];
	//char arr[10];
	double arr[10];
	int sz = sizeof(arr)/sizeof(arr[0]);
	int i = 0;
	for(; i<sz; ++i)
	{
		printf("a[%d]:%p \n", i,&arr[i]);
	}*/

	//code3:
	/*int arr[10];
	printf("%p ",arr);//arr[0]
	printf("%p ",arr+1);//arr[1];类似于指针,int *p = a; p++;对地址加1,其实就是加所选类型的大小;
	printf("%p ",int(arr)+1);//这个是首元素第二个字节的地址*/

	//code4:数组只能整体初始化,不能整体赋值
	//int arr[10];
	//arr+1;//初始化
	//arr = arr+1;//报错,赋值a++

	//code5:
	//int arr[] = {1,2,3,4};
	//printf("%p \n",arr);//数组首元素的地址
	//printf("%p \n",arr + 1);//数组第二个元素的地址
	//printf("%p \n",&arr[1]);//数组第二个元素的地址
	//printf("%p \n",int(arr) + 1);//数组第二个字节的地址
	//printf("%d \n",*(arr+1));//数组第二个元素的内容
	//printf("%d \n",arr[1]);//数组第二个元素的内容
	//printf("%d \n",*&arr[1]);//数组第二个元素的内容

	//code6:栈上的地址是依次减小的,先进后出
	/*int a = 10;
	int b = 20;
	int c = 30;
	printf("%p \n",&a);
	printf("%p \n",&b);
	printf("%p \n",&c);*/

	//code7:数组是整体空间分布的,局部地址是依次增大的,
	//但是把数组不要看成一个个独立个体去开辟空间,数组是整体开辟空间,所以在栈上把空间一次性开辟了。
	//然后把最低地址作为零号下标a[0].
	/*int a = 10;
	int b = 20;
	int c = 30;
	printf("%p \n",&a);
	printf("%p \n",&b);
	printf("%p \n",&c);
	int arr[10];
	int sz = sizeof(arr)/sizeof(arr[0]);
	int i = 0;
	for(; i<10; ++i)
	{
		printf("a[%d]:%p \n", i,&arr[i]);
	}*/

	//code8:数组在全局区,地址也是依次增大的。
	int i = 0;
	for(; i<10; ++i)
	{
		printf("a[%d]:%p \n", i,&arr[i]);
	}
	system("pause");
	return 0;
}
#endif

code1:
在这里插入图片描述
code2:
在这里插入图片描述
在这里插入图片描述
code3:
在这里插入图片描述
code4:
在这里插入图片描述
code5:
在这里插入图片描述
code6:
在这里插入图片描述
在这里插入图片描述
code7:
在这里插入图片描述
在这里插入图片描述
code8:
在这里插入图片描述

3.二维数组

1.二维数组的创建、初始化
 (1)arr[3][4]--->三个元素的一维数组,一维数组里有4int类型的整数
 (2)二维数组第一个维度可以省略,有几行由花括号决定;但第二个维度不能省略
 (3)数组不初始化时为随机值
 (4)二维数组依旧只能初始化,不能赋值
2.遍历二维数组:二维数组在内存中也是连续存储的,且递增的。
3.冒泡排序

3.1 二维数组的创建、初始化

#if 1
#include <stdio.h>
#include <windows.h>
int main()
{   
	//1.二维数组的创建、初始化
	//arr[3][4]--->三个元素的一维数组,一维数组里有4个int类型的整数
	int arr[3][4]={{1,2},{3,4},{5,6}};
	int arr1[][4] = {{1,2},{3,4}};//第一个维度可以省略,有几行由花括号决定;但第二个维度不能省略
	int arr2[3][4];//数组不初始化时为随机值
	//arr2+1;
	//arr2++;//二维数组依旧只能初始化,不能赋值

	system("pause");
	return 0;
}
#endif

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

3.2 遍历二维数组:二维数组在内存中也是连续存储的,且递增的。

#if 1
#include <stdio.h>
#include <windows.h>

int main()
{   //code1:遍历输出二维数组
	/*int arr[4][5] = {{1,2},{3,4},{5,6},{7,8}};
	int i = 0;
	for(;i<4;i++){
		int j = 0;
		for(;j<5;j++){
			printf("arr[%d][%d] = %d : %p\n",i,j,arr[i][j],&arr[i][j]);
		}
	}*/

	//code2:遍历输入二维数组并输出
	int arr[4][5];
	int i = 0;
	for(;i<4;i++){
		int j = 0;
		for(;j<5;j++){
			//scanf("%d",&arr[i][j]);
			arr[i][j] = i*5+j;
		}
	}

	for(i=0;i<4;i++){
		int j = 0;
		for(;j<5;j++){
			printf("arr[%d][%d] = %d : %p\n",i,j,arr[i][j],&arr[i][j]);
		}
	}
	system("pause");
	return 0;
}
#endif

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

3.3 数组传参

1.数组作为函数参数,发生了降维问题,降维成了数组首元素的地址。
在32平台下是4字节,因此数组传参时,一定要传参数组元素的个数,不能再函数中求。
2.冒泡排序

3.3.1 降维处理
#if 1
#include <stdio.h>
#include <windows.h>
void PrintArr(int *arr,int num)
{
	//参数:int *arr,其实是首元素的地址;
	//size=1;因为sizeof(arr)是四字节,数组首元素的地址,
	//在32平台下是4字节,因此数组传承时,一定要传参数组元素的个数,不能再函数中求。
	int size = sizeof(arr)/sizeof(arr[0]);
	printf("%d\n",size);

	int i = 0;
	for(;i<num;i++){
		printf("%d ",arr[i]);
	}
	printf("\n");
}
int main()
{   
	int arr[] = {9,5,3,8,0,4,6,22,2,6};
	int num = sizeof(arr)/sizeof(arr[0]);

	PrintArr(arr,num);
	system("pause");
	return 0;
}
#endif

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

3.3.2 冒泡排序
原理:
(1)每一趟只能确定将一个数归位。
     即第一趟只能确定将末位上的数归位,第二趟只能将倒数第 2 位上的数归位,依次类推下去。
     如果有 n 个数进行排序,只需将 n-1 个数归位,也就是要进行 n-1 趟操作。
(2)而 “每一趟 ” 都需要从第一位开始进行相邻的两个数的比较,
     将较大的数放后面,比较完毕之后向后挪一位继续比较下面两个相邻的两个数大小关系,
	 重复此步骤,直到最后一个还没归位的数。
思路:(1)数组传参需要传参数组名和数组元素的个数
	  (2)i控制趟数,每次将最后一个数归为,需要num-1次;
	  (3)j控制每趟交换的次数,次数由i控制,num-1-i次
	  (4)为了将有序数组快速排序,提高排序效率,用flag==1的方式来判断;
	       如果进行过一轮后,没有比较,flag依旧是1,那么这个数组就是有序的,
		   直接输出就ok,这样效率会更高。
		   如果有进行交换,flag=0,则不是有序数组。
#if 1
#include <stdio.h>
#include <windows.h>
void ShowArr(int *arr,int num)
{
	int i = 0;
	for(;i<num;i++){
		printf("%d ",arr[i]);
	}
	printf("\n");
}
void BubbleSort(int *arr,int num)
{
	int i = 0;
	//控制躺数
	for(;i<num-1;i++){
		//控制每趟的次数
		int j = 0;
		int flag = 1;
		for(;j<num-1-i;j++){
			//判断相邻两个元素是不的大小,进行排序。
			if(arr[j+1]<arr[j]){
				int temp = arr[j];
				arr[j] = arr[j+1];
				arr[j+1] = temp;
				flag = 0;
			}
		}
		//判断是否有序,如果进行过一轮后,发现flag==1,那么这个数组就是有序的,
		//直接输出就ok,这样效率会更高。
		if(flag == 1){
			break;
		}
	}
}
int main()
{   
	int arr[] = {9,5,3,8,0,4,6,22,2,6};
	int num = sizeof(arr)/sizeof(arr[0]);
	ShowArr(arr,num);
	BubbleSort(arr,num);
	ShowArr(arr,num);
	system("pause");
	return 0;
}
#endif

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

4.数组名

1.数组名是数组首元素的地址。
2.sizeof(数组名),计算整个数组的大小,sizeof内部单独放一个数组名,数组名表示整个数组;
&数组名,取出的是数组的地址。&数组名,数组名表示整个数组。

#if 1
#include <stdio.h>
#include <windows.h>
int main()
{   
	//code1:
	int arr[] = {1,2,3,4,5,6};
	printf("%p \n",arr);//首元素的地址
	printf("%p \n",&arr[0]);//第一个元素的地址
	printf("%d \n",*arr);//数组第一个元素

	//code2:
	printf("%p \n",arr);//首元素的地址
	printf("%p \n",arr+1);//第二个元素的地址
	printf("%p \n",arr+2);//第三个元素的地址
	printf("%d \n",*(arr+1));//第二个元素
	printf("%d \n",arr[1]);//第二个元素

	//code3:
	printf("%p \n",arr);//首元素的地址
	printf("%p \n",&arr);//数组的地址
	printf("%p \n",arr+1);//下一个元素的地址
	printf("%p \n",&arr+1);//下一个数组的地址

	//code4:
	int size = sizeof(arr)/sizeof(arr[0]);
	printf("%d \n",size);//数组元素的个数
	printf("%d \n",sizeof(arr));//整个数组的大小
	printf("%d \n",sizeof(arr+1));//第二个元素的大小

	//code5:
	char arr1[] = "asdfghj";
	printf("%d %d\n",strlen(arr1),sizeof(arr1));//strlen字符串内容大小,sizeof字符串包含\0的空间大小
	
	//code6:
	int arr2[] = {1,2,3,(0,4),5};//逗号表达式按照最后一个元素输出
	int num = sizeof(arr)/sizeof(arr[0]);//元素个数5个
	int i = 0;
	for(;i<num;i++){
		printf("%d ",arr2[i]);
	}
	printf("\n");
	printf("%d \n",num);
	system("pause");
	return 0;
}
#endif

在这里插入图片描述
code1:
在这里插入图片描述
code2:
在这里插入图片描述
code3:
在这里插入图片描述
code4:
在这里插入图片描述
code5:
在这里插入图片描述
code6:
在这里插入图片描述

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值