文章目录
数组
变量虽然可以存储数据,但是存放的效率太低了,于是就产生了数组,用来存放一组相同类型的数据。
数组是一组相同类型元素的集合
一、一维数组的创建和初始化
数组的创建方式:
type_t arr_name [const_n];
元素类型 数组名 指定数组的大小
例如:
注意:
- 数组创建,在C99标准之前, [] 中要给一个常量才可以,不能使用变量。在C99标准支持了变长数组的概念,允许数组的大小用变量来指定,如果编译器不支持C99中的变长数组那就不能使用,我使用的vs编译器就不支持变长数组。
- cosnt修饰的n叫常变量,是变量,也不能用它来指定数组的大小。(但是在C++里面const修饰的变量就是常量)
数组的初始化:
数组的初始化是指,在创建数组的同时给数组的内容一些合理初始值。
数组在创建的时候如果想不指定数组的确定的大小就得初始化。数组的元素个数根据初始化的内容来确定。(在变长数组是不能初始化的)
举例:
注意:
全局变量、静态变量(static)未初始化默认赋值为0,因为这两者会放到静态区中。
栈区的局部变量和形式参数,不初始化就是随机值。
本质上放在了不同的区域,初始化赋值是不一样的。
一维数组的使用:
注意:
- [] 下标引用操作符。它其实就数组访问的操作符。
- 数组是使用下标来访问的,下标是从0开始。
- 数组的大小可以通过计算得到。(int sz = sizeof(arr)/sizeof(arr[0]);)
- arr[i] 是访问数组的一个元素,使用变量是没有问题的,i是用来指定数组的下标,要进行区分,不要混淆到一起。
一维数组在内存中的存储:
注意:
- 仔细观察输出的结果,随着数组下标的增长,元素的地址,也在有规律的递增。
- 一维数组在内存中是连续存放的
- %p意味打印16进制,每相邻两个元素之间的地址差4,因为一个整型的大小是4(1,2,3,4,5…这10个元素,每个元素的大小都是4个字节)
- 数组名是数组首元素的地址
- 数组可以通过下标的方式来访问,同时也可以通过指针的方式来访问
- int* p = &arr[0]; p+1其实是跳过了四个字节(一个整形)
二、二维数组的创建和初始化
二维数组的创建:
在内存中的位置:
注意:
- 其他的元素默认为0
- C语言本身是支持多维数组的,但其实很少能用到,例如:int[3][4][5]
二维数组的初始化:
举例:
int arr[3][4]={1,2,3,4};int arr[3][5]={{1,2},{4,5},{5,6}};int arr[][4]={{2,3},{4,5}};//二维数组如果有初始化,行可以省略,列不能省略
注意: 二维数组如果有初始化,行可以省略(行可以根据初始化的内容自己确定),列不能省略。
二维数组的使用:
注意:
- 行和列也是从0开始的
- 还是用[]下标访问操作符
- sizeof(arr) / sizeof(arr[0]) ————求行, sizeof(arr[0])/sizeof(arr[0][0])————求列
二维数组在内存中的存储
通过结果我们可以分析到,其实二维数组在内存中也是连续存储的。
图解方式如下:
三、数组越界
数组的下标是有范围限制的,如果数组的下标如果小于0,或者大于n-1,就是数组越界访问了,超出了数组合法空间的访问。
注意:
- 数组的下标规定是从0开始的,如果数组有n个元素,最后一个元素的下标就是n-1。
- C语言本身是不做数组下标的越界检查,编译器也不一定报错,但是编译器不报错,并不意味着程序就是正确的,所以程序员写代码时,最好自己做越界的检查。
- 二维数组的行和列也可能存在越界。
四、数组作为函数参数
我们在写代码的时候,经常会将数组作为参数传个函数。
举例:冒泡排序(数组中2个相邻的元素进行比较,如果不满足顺序就交换,排序为升序)
注意:
数组名就是数组首元素的地址
但是有两个例外:
1、sizeof(数组名),数组名不是数组首元素的地址,而是整个数组。
2、&数组名,数组名不是数组首元素的地址,数组名表示整个数组,取出的是整个数组的地址。
&数组名+1就是跳过了整个数组
除此这两种情况之外,所有的数组名都表示数组首元素的地址。
总结
以上就是我对于数组的理解,感谢大家的收看!
版权归原作者 Jared612 所有, 如有侵权,请联系我们删除。