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

C语言--数组

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

C语言--数组

1.一维数组 1.1数组的创建

数组是一组相同类型元素的集合。数组的创建方式:

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

 创建数组的实例:

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


int n = 1;
int arr5 [n];
//在c99之前,[]中必须为常量,但在c99中,可以放入变量--支持变长数组的概念。
1.2数组的初始化

数组再创建的同时,我们可以给它一个值。就叫做数组的初始化。

int arr1 [10] = {1,2,3,4,5,6,7,8,9,10};
//完全初始化

int arr1 [10] = {1,2,3};
//不完全初始化,默认其他元素初始值为0

int arr [] = {1,2,3};
//只要初始化,大小可以不指定。大小根据元素的数目创建。

char ch [] = {'a',98,'c'};
//98是字符b的ASCII码值,相当于'b'

char ch0 [] = “abc”;//实际上有a b c  四个元素
char ch1 [] = {'a','b','c'};//有a b c 三个元素

通过最后两个代码,可以引入sizeof和strlen的区别:

strlen是一个库函数,计算的是字符串的长度,仅仅针对字符串,关注字符串中是否有,计算的是之前的字符个数;而sizeof是一个操作符,是用来计算变量所占内存空间大小的,任何类型的数据都可以使用,只关注空间大小,不在乎内存中是否存在。

在这里strlen就是计算字符串长度,不计算,而字符串的结束标志是,而ch2中没有,于是便是后面便是计算机分配的随意值直到到后才结束,所以是15.。

1.3数组的使用

数组的使用可以使用[ ]这个下标引用操作符来访问数组:

需要注意一点下标是从0开始的,之后连续下去

int main()
{
	char ch [10] = { 1,2,3,4,5,6,7,8,9,10 };

    //计算数组的长度
	int sz = sizeof(ch) / sizeof(ch[0]);
	printf("%dn", sz);

    //访问数组中每一个元素
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%dn", ch[i]);
	}

    //向数组中放入元素
    int j = 0;
    for(j = 0; j < sz; j++);
        scanf("%d",&arr[i]); 

	return 0;
}
1.4一维数组在内存中的储存

举个实例来看看元素的地址

int main()
{
	int ch[10] = { 0,5,2,3,4,7,8,9,6,1 };
	int i = 0;
	int sz = sizeof(ch) / sizeof(ch[0]);
	for(i = 0; i < sz; i++)
		printf("%pn", &ch[i]);
	return 0;
}

 每个地址间差4位,是因为int整形数据占四个字节,一个字节给一个地址,而地址只是指向所占第一个字节。所以各差4位。从这里我们可以看出,数组在内存中的存储连续的。

2.二维数组 2.1二维数组的创建

不同于一维数组,二维数组是有行列的。

int ch [3] [4];
2.2二维数组的初始化
//完全初始化
int ch [3] [4] = {1,2,3,4,5,6,7,8,9,10,11,12};
//不完全初始化,会按顺序存储进去,其余的默认为0
int ch [3] [4] = {1,2,3,4,5};

int ch [3] [4] = {{1,2,},{3,4},{5,6}};
//这样的话,第一行前两个就是1,2;第二行前两个就是3,4;第三行前两列就是5,6

//二维数组可以不初始化行,但是必须初始化列
2.3二维数组的使用

和一维数组一样,都是通过下标操作符[]来访问数组的:

//int ch [行] [列],类似于坐标

int main()
{
    int ch[3][4] = { 1,2,3,4,5,6,7,8 ,9,10,11,12 };
    int i, j;
    for (i = 0; i < 3; i++)
    {
        for (j = 0; j < 4; j++)
            printf("%dn", ch[i][j]);
    }
    return 0;
}
2.4二维数组在内存中的储存

与一维数组相同,都是按顺序储存的,储存完一行到下一行。可以想象成是一维数组的数组。

int main()
{
    int ch[3][4] = { 1,2,3,4,5,6,7,8 ,9,10,11,12 };
    int i, j;
    for (i = 0; i < 3; i++)
    {
        for (j = 0; j < 4; j++)
            printf("%pn", &ch[i][j]);
    }
    return 0;
}


3.数组溢出

数组的下标是有范围限制的,数组下标是从0开始到n-1(数组中有n个元素),如果超出这个范围就是数组越界访问了,超出了数组合法空间的访问。而且在C语言中,它是不做数组下标的越界检查,编译器也不一定报错,但不意味着程序就是正确的,所以在写代码时要尤其注意数组越界!

 数组在内存中是连续存储的,所以在第一个元素最后一个元素后也是有数据的:

越界访问到了其他的数据,所以在10后会打印其他奇奇怪怪的数字~


4. 数组可以作为函数的参数 第一种冒泡排序函数

在构造一个函数的时候,数组也可以作为参数传给函数。举一个实例--实现一个冒泡排序函数,将一个整形数组排序。冒泡排序就是两两相邻的元素比较,如果大小符合要求互换数据。

先看这个 代码是否正确:

运行结果 

 并没有起到排序的作用,经过调试发现是sz为1,致使后面的循环进不去。我们由此推断sizeof(arr)大小是4。为什么是这样的?那就不得不提数组名的含义了:

数组名是什么?

数组名是数组首元素的地址(两个例外):

int main()
{
    int arr[] = {1,2,3};
    printf("%pn",arr);
    printf("%pn",&arr[0]);
    printf("%dn",*arr);
    return 0;
}

补充:1.sizeof(数组名),计算整个数组的大小,括号中的数组名表示整个数组;2.&数组名,取出的是数组的地址。&数组名,数组名表示整个数组。除此之外,所有的数组名都表示数组首元素的地址。

冒泡排序函数的正确设计

当数组传参时,实际上是只把数组的首元素的地址传递了过去,即使在函数形参部分写成int arr[]表示的依然是int* arr。所以函数内部的sizeof(arr)结果是4,。函数正确的写法:

本人还有一篇关于数组应用的博客,为了更好地理解数组,大家可以看一看:https://blog.csdn.net/weixin_60720508/article/details/121223546

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

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

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