目录
1. 数组的基本概念
数组是含有多个数据值的数据结构,并且每个数据值具有相同的数据类型。这些数据值称为元素(element),可以根据元素在数组中所处的位置把它们一个个地选出来。
2. 一维数组的创建和初始化
2.1 数组的创建
数组是一组相同类型元素的集合。
数组的创建方式:
type_t arr_name [const_n]
//type_t 是指数组的元素类型
//const_n 是一个常量表达式,用来指定数组的大小
2.2 数组的初始化
数组的初始化是指,在创建数组的同时给数组的内容一些合理初始值(初始化)。
一些基本规则:
数组初始化器最常见的格式是一个用花括号括起来的常量表达式列表,常量表达式之间用逗号进行分隔:
int arr[10]={1, 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10}
如果初始化器比数组短;,那么数组剩余的元素赋值为0:
int arr[10]={1 , 2 , 3 , 4 , 5 , 6};
/* initial value of arr is {1, 2, 3, 4, 5, 6, 0, 0, 0, 0 }*/
利用这一特性,就可以很容易地把数组全部初始化为0:
int arr[10]={0};
初始化器为空是错误的,同时初始化器比要初始化的数组长也是错误的。
当然如果给定了初始化器,就可以省略数组的长度:
int arr[]={1, 2, 3, 4, 5, 6};
最后数组也可以储存字符类型:
char arr[3]={ 'a' , 'b' , 'c' };
char arr[ ]={ 'a' , 98 , 'c' };
char arr[ ]="abcdef";
在我们数组的初始化和创建的过程中同时也要学会区分下面代码的区别:
char arr1[] = { 'a','b','c' };
char arr2[] = "abc";
我们通过在屏幕上打印它们自身字符串和所占内存字节数的方式认识它们的不同:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{
char arr1[] = { 'a','b','c' };
char arr2[] = "abc";
printf("%d\n", sizeof(arr1));
printf("%d\n", sizeof(arr2));
printf("%s\n", arr1);
printf("%s\n", arr2);
return 0;
}
结果如下:
产生这样的不同是因为‘\0’在其中发挥作用,第二段代码的最后隐藏这一个'\0',它其实是判断字符串是否结束的标志,就是通过判断是否遇到了'\0',如果遇到则表示字符串结束。所以在打印第一段代码的字符串因为找不到'\0'的结束标志,才会打印出类似烫烫烫的随机值。直到找到在后面的'\0'才结束了打印。
2.3 一维数组的使用
我们可以通过:[ ] (下标引用操作符),来访问数组。举例如下:
//一维数组的访问
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{
int arr[10] = { 0,1,2,3,4,5,6,7,8,9 };
int i = 0;
int sz = sizeof(arr) / sizeof(arr[0]);//计算元素个数
for (i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
总结: 数组是通过下标来访问的,下标从0开始。
2.4 一维数组在内存中的存储
为了方便研究,我们在屏幕打印出arr[10]={0};的各个元素所在的地址。代码如下:
//一维数组在内存中的储存
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{
int arr[10] = { 0 };//不完全初始化
int sz = sizeof(arr) / sizeof(arr[0]);
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%p\n", &arr[i]);
}
return 0;
}
会产生什么样的结果呢 ???
通过观察我们可以发现,随着数组下标的增长,元素的地址,也在有规律的递增。有此我们可以得出结论:数组在内存中是连续存放的。随着下标的增加,由低地址到高地址。
3. 二维数组的创建和初始化
3.1 二维数组的创建
//数组创建
int arr[3][4];
char arr[3][5];
char arr[2][4];
3.2 二维数组的初始化
//数组初始化
int arr[3][4]={1,2,3,4};
int arr[3][4]={{1,2},{4,5}};
int arr[ ][4]={{2,3},{4,5}};//二维数组如果有初始化,行可以省略,列不能省略。
3.3 二维数组的使用
二维数组的使用也是通过下标的方式。
代码如下:
//二维数组的访问
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{
int arr[3][4] = { 0 };
int i = 0;
int j = 0;
for (i = 0; i < 3; i++)
{
for (j = 0; j < 4; j++)
{
arr[i][j] = i * 4 + j;
}
}
for (i = 0; i < 3; i++)
{
for (j = 0; j < 4; j++)
{
printf("%-2d ", arr[i][j]);
}
printf("\n");
}
return 0;
}
产生结果:
3.4 二维数组的在内存中的存储
和研究一维数组一样的方法,看代码:
//二维数组在内存中的存储
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{
int arr[3][4] = { 0 };
int i = 0;
int j = 0;
for (i = 0; i < 3; i++)
{
for (j = 0; j < 4; j++)
{
printf("&arr[%d][%d]=%p\n", i, j, &arr[i][j]);
}
}
return 0;
}
产生结果:
进过观察我们同样可以发现,二维数组在内存中也是连续存储的。
4. 数组越界
数组的下标是有范围限制的。
数组的下规定是从0开始的,如果数组有n个元素,最后一个元素的下标就是n - 1。
所以数组的下标如果小于0,或者大于n - 1,就是数组越界访问了,超出了数组合法空间的访问。
C语言本身是不做数组下标的越界检查,编译器也不一定报错,但是编译器不报错,并不意味着程序就
是正确的,
所以程序员写代码时,最好自己做越界的检查。
5. 数组名是什么
数组名是首元素的地址(有两个意外):
(1)sizeof(数组名),数组名如果单独放在sizeof内部,这里的数组名表示整个数组,计算的是整个数组的大小。
(2)&数组名,这里的数组名表示整个数组,取出的是整个数组的地址。
今天分享就到这里,希望大家一起提高!