本人0基础开始学编程,我能学会的,你也一定可以,学会多少写多少。
下载安装请从官网入手,社区版本即可,这里主要使用的软件是VS2019,图标如下。
上一篇:从0开始学c语言-14-关于(3)函数递归、递归与迭代、栈溢出、练习求第n个斐波那契数、用递归思想求字符串的长度_阿秋的阿秋不是阿秋的博客-优快云博客
相关数组文章:
从0开始学c语言-04-神奇的\0、数组初始化、求字符长度_阿秋的阿秋不是阿秋的博客-优快云博客
从0开始学c语言-06-选择语句、循环语句、函数、数组_阿秋的阿秋不是阿秋的博客-优快云博客
目录
1·一维数组的创建和初始化
数组的创建
int arr1[10]; //数据类型为int、名为arr1、大小为10个元素的数组
int | arr1 | 10 |
数组的元素类型 | 数组的名字 | 常量表达式,指定数组大小 |
什么叫常量表达式?
只要这个表达式的结果是常量就好,常量就是不会改变的量。
(不懂的去看这篇:从0开始学c语言-03-变量和常量_阿秋的阿秋不是阿秋的博客-优快云博客)
像arr3这样的就不可以,因为a和b都是变量,他们表达式的结果也是变量。
所以在创建数组的时候[ ]里面必须是常量表达式。
但是在访问数组的时候可以使用变量,就像这样
可以看到,用变量访问数组,i如果超出访问范围也是会警告的。
数组的初始化
这里不再进行深入讲解,请看从0开始学c语言-04-神奇的\0、数组初始化、求字符长度_阿秋的阿秋不是阿秋的博客-优快云博客
务必区分好这样的数组,在内存中储存的区别。
char arr1[] = "abc";
char arr2[3] = {'a','b','c'};
同时也要学会调试来看数组中的元素组成,都在上面的文章里。
int arr1[10] = {1,2,3};
int arr2[] = {1,2,3,4};
int arr3[5] = {1,2,3,4,5};
能够分清楚上面这几种数组里储存的是什么,还要能够判别下面这段代码中的98储存的字符是什么。这里放上网址:ASCII码对照表-完整ASCII码表-我就查查询
char arr4[3] = {'a',98, 'c'};
可以看到储存的字符是'b',打印的时候记得用%c的形式,%d则会打印98。
2·一维数组的使用
我们使用[ ]配合数组名和下标来访问数组。
不知道下标的看这篇从0开始学c语言-06-选择语句、循环语句、函数、数组_阿秋的阿秋不是阿秋的博客-优快云博客
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;
}
要学会计算数组元素个数的方法,sizeof(arr)代表整个数组的大小,sizeof(arr[0])代表数组中第一个元素的大小。
后面的两个循环只是为了展示数组怎么赋值的,怎么输出内容的。
一定要记住这个计算数组元素个数的方法。
int sz = sizeof(arr)/sizeof(arr[0]);
3·一维数组在内存中的存储
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;
}
可以看到,数组中元素的地址是连续的,每个元素占4个字节大小(因为是int类型)。
不懂为什么是4个字节大小的看这篇
从0开始学c语言-02-关于数据类型_阿秋的阿秋不是阿秋的博客-优快云博客
可以看到,数组在内存中是连续存放的,随着数组下标的增长,元素的地址也随之递增。
1·二维数组的创建和初始化
二维数组的创建
int arr[3][4]; //int类型、arr名字、3行4列的二维数组
二维数组初始化
//初始化——创建的同时进行赋值
int arr1[2][3] = {1,2,3,4}; //不完全初始化
我们调试来看一看。
可以看到在类型中的划分,数组会把每一行行划分为一维数组int[3]类型
那么我们把就可以第一行的元素叫arr1[0],第二行的元素叫arr1[2]
现在我们可以这样初始化
//把每一行看做一维数组,用{}和逗号进行区分并赋值
int arr2[2][3] = {{1,2},{4,5}};
哦吼,有意思的呢,可以这样分行赋值了!
还可以这么写
//行可以省,列不能省
int arr3[][3] = {{2,3},{4,5}};
至于为什么列不能省,我们等会再说。
那么大概就是这三种初始化方式了。
//初始化——创建的同时进行赋值
int arr1[2][3] = { 1,2,3,4 }; //不完全初始化
//把每一行看做一维数组,用{}和逗号进行区分并赋值
int arr2[2][3] = { {1,2},{4,5} };
//行可以省,列不能省
int arr3[][3] = { {2,3},{4,5} };
2·二维数组的使用
二维数组一定要分清楚行和列就可以了,访问依旧是下标的方式(从0开始)。
int main()
{
int arr[][4] = { {1,2},{2,3},{4,5} };
int a = 0;
int b = 0;
for (a = 0; a < 3; a++) //每一行
{
for (b = 0; b < 4; b++) //每一列
{
printf("%d ", arr[a][b]);
//这个语句换成arr[a][b] = a+b;的话就是在进行初始化赋值
}
printf("\n"); //换行
}
return 0;
}
3·二维数组在内存中的储存
int main()
{
int qiu[][4] = { {1,2},{2,3},{4,5} };
int a = 0;
int b = 0;
for (a = 0; a < 3; a++) //每一行
{
for (b = 0; b < 4; b++) //每一列
{
printf("&qiu[%d][%d]=%p\n", a ,b ,&qiu[a][b]);
//数组本身不就是地址嘛,为啥这里还需要加取地址符号呢
//数组本身代表首字母地址,加取地址符是取数组内指定元素地址
}
printf("\n"); //换行
}
return 0;
}
可以看到,二维数组的地址是连续的。
二维数组在内存中的地址是连续的,换行也是连续的,这就是为什么列不能省略,因为它需要知道这一行有几个元素,才能分行。
既然二维数组的地址是连续的,那么我们还可以这样访问数组。
int main()
{
int qiu[][4] = { {1,2},{2,3},{4,5} };
int a = 0;
int b = 0;
int i = 0; //下标
int* p = &qiu[0][0]; //首元素的地址
for (i = 0; i < 12; i++)
{
printf("%d ", *p); //因为*p返回类型是int
p++;
//p是地址,* p是该地址内存储的值,对地址p++,代表对地址p + 1跳到下一个元素
}
return 0;
}
我们之前说,可以第一行的元素叫arr1[0],第二行的元素叫arr1[2]
既然说地址是连续的,我们打印验证一下
可以看到,
arr[0]代表第一行的第一个元素
arr[1]代表第二行的第一个元素
以此类推……
1·数组越界
2·数组作为函数参数
补充:
数组的长度 是 数组的空间大小,不是字符串的长度。
两个数组进行交换,不能直接创建中间数组。因为数组名是首元素的地址,所以我们要采用直接交换数组元素的方式进行交换。