C语言学习笔记之数组篇

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

目录

一维数组

数组的创建

数组的初始化

数组的使用

数组在内存中的存储

二维数组

数组的创建

数组的初始化

数组的使用

数组在内存中的存储

数组名

数组名作函数参数


一维数组

数组的创建

type_t  arr_name  [const_n];
//type_t 是指数组的元素类型
//arr_name是数组的名字,命名遵循C语言命名规则
//const_n 是一个常量表达式,用来指定数组的大小

数组的初始化

数组初始化时可以不指定数组大小,此时初始化的元素个数就是数组的大小。

在指定数组的大小后,如果初始化的元素个数小于数组元素的个数,则剩余元素初始化为0。(元素与元素之间用**,**隔开)

int arr1[] = { 1, 2, 3, 4};
int arr2[5] = { 1,2,3,4,5 };
int arr3[10] = { 1, 2, 3 };

初始化字符数组时,要用 ' ' 将要初始化的字符括起来或者用字符对应的ASCII码初始化。

char arr4[3] = { 'a', 98, 'c'};
char arr5[] = { 'a', 'b', 'c'};

可以用一个 "字符串" 初始化字符数组,此时数组结尾默认加一个字符串结束标志 '\0'。(数组大小必须大于等于字符串字符个数加1)

char arr6[] = "abcdef";
char arr7[] = "";

数组的使用

可以通过下标引用操作符 [ ] (创建数组时的 [ ] 不是下标引用)用下标访问数组元素。对于一个有 n 个元素的数组,数组元素下标从0开始,到 n - 1 结束。

#include <stdio.h>

int main()
{
	int arr[10] = { 0 };
	int i = 0;
	//遍历数组
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");
	//给数组每个元素赋值
	for (i = 0; i < 10; i++)
	{
		arr[i] = i;
	}
	//打印下标为5的数组元素值
	printf("%d\n", arr[5]);
	//遍历数组
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

数组的大小可以通过关键字 sizeof 计算获得。(sizeof用来计算类型大小)。

#include <stdio.h>

int main()
{
	int arr[10] = { 0 }; //此数组类型:int[10], 每个数组元素的类型:int

	int sz = sizeof(arr) / sizeof(arr[0]);
	printf("%d\n", sz);

	return 0;
}

数组在内存中的存储

数组在内存中是连续存放的(低地址到高地址)。

#include <stdio.h>

int main()
{
	int arr[10] = { 0 };
	int i = 0;
	int sz = sizeof(arr) / sizeof(arr[0]);

	for (i = 0; i < sz; ++i)
	{
		printf("&arr[%d] = %p\n", i, &arr[i]);
	}
	return 0;
}

二维数组

数组的创建

type_t  arr_name  [const_n1][const_n2];
//type_t 是指数组的元素类型
//arr_name是数组的名字,命名遵循C语言命名规则
//const_n1 是一个常量表达式,用来指定数组的行数
//const_n2 是一个常量表达式,用来指定数组的列数

数组的初始化

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

先初始化完一行,才会初始化下一行,如果初始化的元素个数小于数组元素的个数,则剩余元素初始化为0。

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

可以用 { } 初始化指定行。

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

二维数组如果有初始化,行可以省略,列不能省略。(原因在二维数组在内存中的存储)

数组的使用

二维数组的使用与一维数组类似,也是通过下标来访问的(行和列下标都是从0开始)。

#include <stdio.h>

int main()
{
	int arr[3][4] = { 0 };
	int i = 0;
    //赋值
	for (i = 0; i < 3; i++)
	{
		int j = 0;
		for (j = 0; j < 4; j++)
		{
			arr[i][j] = i * 4 + j;
		}
	}
    //打印
	for (i = 0; i < 3; i++)
	{
		int j = 0;
		for (j = 0; j < 4; j++)
		{
			printf("%-2d ", arr[i][j]); //%-2d:右对齐,不够两位数补空格
		}
		printf("\n");
	}
	return 0;
}

数组在内存中的存储

二维数组在内存中也是连续存放的(低地址到高地址)。

#include <stdio.h>

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

因此对于二维数组,我们也可以这样理解:二维数组就是每个元素是一维数组的数组。

因为二维数组在内存中连续存放,所以二维数组的行可以省略,列不能省略,因为如果省略了列,就无法确定每一行有多少个元素,从而不知道下一行的起点。

数组名

无论是一维数组还是二维数组,数组名都表示的是首元素的地址 。(两种例外情况:&数组名 和 **sizeof(数组名)**中数组名表示的是整个数组)

#include <stdio.h>

int main()
{
	int arr1[10];
	int arr2[3][4];
	printf("&arr1[0] = %p\n", &arr1[0]); //打印首元素的地址
	printf("arr1 = %p\n", arr1);

	printf("&arr2[0][0] = %p\n", &arr2[0][0]); //打印首元素的地址
	printf("arr1 = %p\n", arr1);

	return 0;
}

&数组名:

#include <stdio.h>

int main()
{
	int arr1[10];
	int arr2[3][4];

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

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

	return 0;
}

sizeof(数组名):

#include <stdio.h>

int main()
{
	int arr1[10];
	int arr2[3][4];
	
	printf("sizeof(arr1[0]) = %d, sizeof(arr1) = %d\n", sizeof(arr1[0]), sizeof(arr1));

	printf("sizeof(arr2[0][0]) = %d, sizeof(arr2) = %d\n", sizeof(arr2[0][0]), sizeof(arr2));

	return 0;
}

数组名作函数参数

void test1(int arr[]) //因为数组名表示首元素地址,所以等价于void test(int* arr)
{

}

void test2(int arr[][4])//二维数组行可以省略,列不能省略,等价于void test2(int (*arr)[4])//数组指针(指针篇)
{

}

#include <stdio.h>

int main()
{
	int arr1[10];
	int arr2[3][4];
	test1(arr1);
	test2(arr2);
	return 0;
}
相关推荐
幸运超级加倍~31 分钟前
软件设计师-上午题-15 计算机网络(5分)
笔记·计算机网络
南宫生38 分钟前
贪心算法习题其四【力扣】【算法学习day.21】
学习·算法·leetcode·链表·贪心算法
懒惰才能让科技进步1 小时前
从零学习大模型(十二)-----基于梯度的重要性剪枝(Gradient-based Pruning)
人工智能·深度学习·学习·算法·chatgpt·transformer·剪枝
DARLING Zero two♡1 小时前
关于我、重生到500年前凭借C语言改变世界科技vlog.16——万字详解指针概念及技巧
c语言·开发语言·科技
love_and_hope2 小时前
Pytorch学习--神经网络--搭建小实战(手撕CIFAR 10 model structure)和 Sequential 的使用
人工智能·pytorch·python·深度学习·学习
Chef_Chen2 小时前
从0开始学习机器学习--Day14--如何优化神经网络的代价函数
神经网络·学习·机器学习
芊寻(嵌入式)2 小时前
C转C++学习笔记--基础知识摘录总结
开发语言·c++·笔记·学习
QAQ小菜鸟2 小时前
一、初识C语言(1)
c语言
准橙考典2 小时前
怎么能更好的通过驾考呢?
人工智能·笔记·自动驾驶·汽车·学习方法
hong1616882 小时前
跨模态对齐与跨领域学习
学习