c语言数组
一. 一维数组
1. 一维数组的创建
1 数组是什么?(数组的定义)
数组是相同类型元素的集合
2 数组的创建方式
int main()
{
//数组的创建方式
// type_t arr_name [const_n}
// type_t 是指数组的元素类型
// const_n 是一个常量表达式 用来指定数组的大小
return 0;
}
不过这里有一点要注意的是 在c语言的c99标准中支持了变长数组的概念 即数组的大小可以使用变量指定
但是数组不能初始化
2. 一维数组的初始化
1 什么是初始化?
初始化就是指 在创建数组的同时给数组内的内容一些合理化的数值
2 写出一些数组初始化的代码
代码如下
int main()
{
int arr1[10] = { 1,2,3 };
int arr2[] = { 1,2,3,4 };
int arr3[5] = { 1,2,3,4,5 };
char arr4[3] = { 'a',98,'c' };
char arr5[] = { 'a','b','c' };
char arr6[] = "abcdef";
return 0;
}
3 请区分以下两个数组有多少个元素
char arr1[] = "abc";
char arr2[] = { 'a','b','c' };
char arr3[3] = { 'a','b','c' };
char arr4[5] = { 'a','b'};
正确答案 应该是 4 3 3 5
大家可以使用sizeof操作符验证一下
至于为什么arr1[]的大小是4呢?
其实是因为在初始化字符串“abc”的时候后面有个默认的转义字符\0
它的ascll码值是0 占一个字节
所以arr1才占四个字节的大小
4 扩展题
char arr1[] = "abc";
char arr2[] = { 'a','b','c' };
char arr3[3] = { 'a','b','c' };
char arr4[5] = { 'a','b'};
它们的字符串长度分别是多少呢?
为什么?
正确答案是 3 随机数 随机数 2
strlen的脾气比较倔 不知道变通 它统计字符串长度的时候一定要遇到’\0’才肯罢休
arr1上面已经讲解了 它的第四个字符是\0 所以说返回值是3
arr2呢 数组后面的值是随机值 并不知道什么时候会遇到‘\0’ 所以说会返回一个随机值
arr3呢 虽然数组初始化为3了 但是strlen一定要找到’\0‘才会停止 所以说会返回一个随机值
arr4呢 数组未完全初始化 而后面的值会默认初始化为0 我们上面讲过了 ’\0‘的ascll码值就是0 所以说返回的长度是2
3. 一维数组的使用
对于数组的使用我们介绍操作符的时候介绍了:[],下标引用操作符
int main()
{
int arr[10] = { 0 };//数组的不完全初始化
// 计算数组的元素个数
int sz = sizeof(arr) / sizeof(arr[0]);
//对数组内容赋值
int i = 0;
for ( i = 0; i < sz; i++)
{
arr[i] = i;
}
for ( i = 0; i < sz; i++)
{
printf("%d\n", arr[i]);
}
return 0;
}
总结一下
1 数组是使用下标来访问的 下标打大小是从0开始的
2 数组的大小是可以通过计算得到的 计算公式如下
int sz = sizeof(arr) / sizeof(arr[0]);
4. 一维数组在内存中的存储
代码如下
int main()
{
int arr[10] = { 0 };
int i = 0;
int sz = sizeof(arr) / sizeof(arr[0]);
for ( i = 0; i < sz; i++)
{
printf("%p\n", &arr[i]);
}
return 0;
}
输出结果如下
观察输出结果 我们可以得到以下结论
一维数组在内存中是连续存放的
二. 二维数组
1. 二维数组的创建
代码如下
int arr[3][4];
char arr2[3][4];
double arr[2][4];
2. 二维数组的初始化
这里需要注意的一点是 二维数组初始化的时候行可以省略 列不可以省略
int arr[3][4] = { 1,2,3,4 };
int arr[3][4] = { {1,2},{3,4} };
int arr[][4] = { {1,2},{3,4} };
3. 二维数组的使用
代码如下
int main()
{
int arr[3][5] = { 1,2,3,4,5,6,7,8,9,10 };
int i = 0;
for ( i = 0; i < 3; i++)
{
int j = 0;
for ( j = 0; j < 5; j++)
{
printf("%d\n", arr[i][j]);
}
}
return 0;
}
4. 二维数组在内存中的存储
代码如下
int main()
{
int arr[3][5] = { 1,2,3,4,5,6,7,8,9,10 };
int i = 0;
for (i = 0; i < 3; i++)
{
int j = 0;
for (j = 0; j < 5; j++)
{
printf("%p\n", &arr[i][j]);
}
}
return 0;
}
结果如下
由此我们可以得出结论
二维数组在内存中是连续存储的
联合一维数组在内存中存储的结论 我们可以大胆推断出
数组在内存中是练习存储的
三. 数组越界
数组的下标是有范围限制的。
数组的下标从0开始 如果数组有n个元素 则最后一个元素的下标就是n-1
所以数组的下标如果小于0 或者大于n-1 就是数组越界访问了 超出了数组合法空间的访问
c语言本身不错下标的越界检查 编译器也不一定报错
所以我们在写数组的时候要自己检查 以免犯错
四. 数组作为参数传参
1. 冒泡排序实现数组排序
实现代码如下
void bubble_sort(int arr[10], int sz)
{
int i = 0;
for ( i = 0; i < sz-1; i++)
{
int j = 0;
for ( j = 0; j <sz-1-i; j++)
{
if (arr[j]>arr[j+1])
{
int tmp = arr[j+1];
arr[j + 1] = arr[j];
arr[j] = tmp;
}
}
}
}
int main()
{
int arr[10] = { 10,9,8,7,6,5,4,3,2,1 };
int sz = sizeof(arr) / sizeof(arr[0]);
bubble_sort(arr, sz);
int i = 0;
for (size_t i = 0; i < sz; i++)
{
printf("%d\n",arr[i]);
}
return 0;
}
这里博主写这段代码的时候出现了一点失误
在最后j循环交换的时候写成了
int tmp = arr[i+1];
最终导致找了好久都没有发现错误
希望大家写代码的时候还是要细心啊
这里还有一个注意点
sz的计算必须要在主函数内计算 而不能在冒泡排序计算
因为arr传递的是数组的首元素地址 而不是整个数组
具体的细节 博主在函数栈帧中有详细解释 大家感兴趣的话可以去看看
函数栈帧
2. 数组名是什么?
数组名在大部分情况下表示的是首元素地址
两张情况下除外
1 在sizeof(arr)中 arr表示是整个数组
2 在&arr中 arr表示的也是整个数组
可能有些同学会好奇 &arr的结果打印出来明明是首元素地址啊 那这为什么和arr[0]不同呢?
我们说:当创建两个指针分别指向arr和arr[0]的时候
指向arr的指针每次移动的大小是整个数组的大小
指向 arr[0]的指针每次移动的大小是元素所占空间的大小
以上
由于本人知识的不足可能出现各种错误 希望大佬看到可以在评论区指出
如果有c语言相关的问题可以通过私信发我 看到就会回的
下期再见~