栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C初阶——数组

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C初阶——数组

目录

一、一维数组

1.一维数组的创建

2.一维数组的初始化

3.一维数组的使用

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

二、二维数组

1.二维数组的创建

2.二维数组的初始化

3.二维数组的使用

4.二维数组在内存中的存储

三、数组越界

四、数组作为函数参数

1.什么是冒泡排序

2.冒泡排序函数的错误设计

3.数组名是什么?

4.冒泡排序函数的正确设计


一、一维数组

1.一维数组的创建

数组是一组相同类型元素的集合。

数组的创建方式:

type_t  arr_name[const_n];
 
//type_t:指数组元素类型
//arr_name:数组名
//const_n:一个常量表达式,用来指定数组的大小

错误案例:

int n = 10;
int arr[n];

【注意】:数组的创建,在C99标准之前,[ ]中要给一个常量才可以,不能使用变量。在C99之后支持了变长数组的概念,允许数组的大小是变量,但是对编译器有所要求,要求编译器支持C99标准。但是有很多编译器对C99的支持就不够好,所以严重不推荐这样写。

正确实例:

int arr1[10];
char arr2[5];
float arr3[20];

2.一维数组的初始化

数组的初始化是指,在创建数组的同时给数组的内容一些合理的初始值。

代码如下

int arr1[10]={1,2,3};
int arr2[]={1,2,3,4,5};
int arr3[5]{1,2,3,4,5};
char arr4[3]={'a','66','A'};
char arr5[]={'a','b','c'};
char arr6[]={"abcdef"};

一维数组创建的时候如果想不指定数组的确定大小就得初始化,数组的元素个数通过初始化的内容来确定。

对于字符数组要格外注意:

char arr5[]={'a','b','c'};//末尾没有
char arr6[]={"abcdef"};//字符串末尾有

sizeof(arr5) -->3

strlen(arr5) -->乱码!

【说明】:注意比较strlen() 和sizeof()

strlen() 是一个库函数,计算的是字符串的长度,并且只能作用于字符串,关注点在于字符串中是否有 ,计算的是字符串 之前的字符个数;sizeof 是一个操作符,sizeof 是用来计算变量所占空间大小的,任何类型都可以使用,只关注空间大小,不在乎内存中是否有, 而且单位是字节。
 

3.一维数组的使用

直接看代码:

#include
int main()
{
	int arr[10] = { 0 };
	//计算数组的元素个数
	int sz = sizeof(arr) / sizeof(arr[0]);
	//对数组进行赋值,数组是使用下标进行访问的,下标是从0开始的,所以
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		arr[i] = i;
	}
	//输出数组内容
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

总结:

数组是使用下标来访问的,下标是从0开始的;数组的大小可通过计算得到

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

下面我们探讨一维数组在内存中的存储

看代码

【总结】:

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

二、二维数组

1.二维数组的创建
int arr1[3][3];
char arr2[5][3];
double arr3[10][4];

2.二维数组的初始化
int arr1[3][4]={1,2,3,4};
int arr2[3][4]={{1,2},{3,4}};
int arr3[ ][4]={{2,3},{5,6}};//在二维数组中初始化时,行可以省略,列一定不能省略
int arr4[][]={{2,3},{5,6}};//错误
int arr4[3][]={{2,3},{5,6}};//错误

3.二维数组的使用

二维数组的使用也是通过下标的方式

#include
int main()
{
	int arr[3][4] = { 0 };
	int i = 0;
	for (i = 0; i < 3; i++)
	{
		int j;
		for (j = 0; j < 4; j++)
			arr[i][j] = i * 4 + j;//对每个元素进行赋值
	}
	for (i = 0; i < 3; i++)
	{
		int j;
		for (j = 0; j < 4; j++)
			printf("%d ", arr[i][j]);//打印每个元素
	}
	return 0;
}

4.二维数组在内存中的存储

我们和一维数组一样的每个元素的地址

 通过结果我们可以得出结论

二维数组在内存中的存储:也是连续存放的!

三、数组越界

数组的下标是有范围限制的,规定数组的下标从0开始,如果数组有N个元素,那么最后一个元素的下标是N - 1,所以数组下标如果小于0 或者大于 N - 1,就属于越界访问了,超出了数组合法空间的访问。

C语言本身不作数组下标的越界检查,编译器也不一定报错,但是编译器不报错并不意味着程序是正确的。而且二维数组的行列也可能存在越界。

所以写代码时,最好自己做越界的检查。

四、数组作为函数参数

1.什么是冒泡排序

以升序为例,

依次比较相邻的两个数,将比较小的数放在前面,比较大的数放在后面,

每一趟冒泡排序都是把一个最大的元素放到最后面的过程。

2.冒泡排序函数的错误设计
#include
void bubble_sort(int arr[])
{
	int sz= sizeof(arr) / sizeof(arr[0]);
	int i;
	for (i = 0; i < sz; i++)
	{
		int j;
		for (j = 0; j < sz - i - 1; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				int tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
			}
		}
	}
}
int main()
{
	int arr[] = { 3,5,7,1,2,6,8,9,4,0 };
	bubble_sort(arr);
	int i;
	for (i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

这段代码有什么问题呢???

通过调试我们可以发现bubble_sort函数内sz,为1

这又是为什么呢?

我们往下看

3.数组名是什么?

一般情况下,数组名是首元素的地址,但是有两个特例:

sizeof(数组名):计算的是整个数组的大小,此时的数组名表示的是整个数组;&数组名:取出的是整个数组的地址,此时的数组名表示的是整个数组。

除了上面两种情况,所有的数组名都表示数组首元素的地址!

4.冒泡排序函数的正确设计

当数组传参的时候,实际上只是把数组首元素的地址传递过去了。

所以即使在函数的参数部分写成数组的形式:int arr[]依然表示的是一个指针int* arr

所以函数内部的sizeof(arr)计算的是指针变量的大小

那么,函数内部的sizeof(arr)为4,

所以,sz就为1。

那么,我们应该怎么写呢?

#include
void bubble_sort(int arr[],int sz)//参数接收数组元素个数
{

	int i;
	for (i = 0; i < sz; i++)
	{
		int j;
		for (j = 0; j < sz - i - 1; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				int tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
			}
		}
	}
}
int main()
{
	int arr[] = { 3,5,7,1,2,6,8,9,4,0 }; 
	int sz=sizeof(arr) / sizeof(arr[0]);
	bubble_sort(arr,sz);
	int i;
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

所以我们在把数组传参给函数时,在函数内部我们是无法通过sizeof求数组大小的

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/717610.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号