目录
一、一维数组的创建和初始化
1.数组的创建
type_t arr_name [ const_n ];//type_t 是指数组的元素类型//const_n 是一个常量表达式,用来指定数组的大小
数组的一般形式为:
数组的元素类型 数组名[常量表达式]
说明:常量表达式中可以包括常量和符号常量,如“int a[3+5];”是合法的。不能包含变量,如, “int b[n];”是不合法的。C语言不允许对数组的大小作动态定义。
int n=0;
scanf("%d",&n);
int arr[n];
这些局部变量或者数组是存放在栈区的,如果不初始化,默认是随机值。
补充:C99标准之前,数组的大小只能用常量表达式
C99标准引入了变长数组的概念,使得数组在创建的时候可以使用变量,但是这样的数组不能初始化
2.数组的初始化
(1)在定义数组是对全部数组元素赋予初值 完全初始化
将数组中各元素的初值顺序放在一对花括号内,数据间用逗号隔开,花括号内的数据就成为“初始化列表”。
int arr[10]={0,1,2,3,4,5,6,7,8,9};
(2)可以只给数组中一部分元素初始化 不完全初始化
int arr[10]={1,2,3};
定义a数组有10个元素,但花括号内只提供3个初值,只给前面3个元素赋初值,系统会自动给剩余的元素都默认为0
(3)如果想使整个数组中元素全为0,可以写成
int arr[10]={0}; 未赋值的元素系统自动赋值为0
(4)省略数组的大小,数组必须初始化,数组的大小是根据初始化的内容来确定
花括号中有几个数,数组的大小就为几
例如: int arr[ ]={5,6,7,8};
字符初始化
字符串初始化有'\0'
3.数组的引用
注意:只能引用数组元素而不能一次整体调用整个数组全部元素的值
引用数组的形式
数组名 [下标]
数组的下标是从零开始递增1往后走 数组是使用下标来访问的 例如:arr[0]就是数组中的第一个元素
注意:定义数组名时用到的“数组名[常量表达式]”和引用数组元素时用的"数组名[下标]"形式相同,但含义不同
数组的大小是可以通过计算得到的
int main()
{
int arr[10]={0,1,2,3,4,5,6,7,8,9}; //一个整型4给字节 10*4
printf("%d\n", sizeof(arr)); 40 //计算数组总的大小 单位是字节
printf("%d\n", sizeof(arr[0])); 4 //一个元素的大小
int sz = sizeof(arr) / sizeof(arr[0]); //计算元素个数的方法
printf("%d\n", sz);
return 0;
}
4.一维数组在内存中的存储
16进制: 0 1 2 4 5 6 7 8 9 a(10) b(11) c(12) d(13) e(14) f(15)
数组的创建是连续存放的,数组在内存中是由低地址到高地址一次存放的
二、二维数组的创建和初始化
1.二维数组的创建
数组的元素类型 数组名[常量表达式][常量表达式]
例如:int a[3][4]
对于二维数组我们可以这样理解:
把a看作一个一维数组,它有三个元素 a[0],a[1],a[[02]
再把a[0],a[1],a[2]看作三个一维数组的数组名,每个数组有含有4个元素
a[0] - - - - a[0][0] a[0][1] a[0][2] a[0][3]
a[1] - - - - a[1][0] a[1][1] a[1][2] a[1][3]
a[2] - - - - a[2][0] a[2][1] a[2][2] a[2][3]
2.二维数组的初始化
(1)分行给二维数组赋初值
int a[3][4]={{1,2,3,4},{2,3,4,5},{3,4,5,6}};
这种方式比较直观,打第一个花括号内的数据给第一行元素,即按行赋值。
(2)将所有数据放在一个花括号,这样第一行元素排满后,再排下一行
int arr[3][4]={1,2,3,4};
(3)可以对部分元素赋值
int arr[3][4]={ { 1,2 },{ 5,6} };
4)二维数组行标可以省略,但列表不可以省略
int arr[ ][4]={{1,2,3,4},{2,3,4,5},{3,4,5,6}};
二维数组在内存中是连续存放的,要知道一行几个元素。所以列不可以省略
二维数组行和列都是从0开始的
3.二维数组的使用
二维数组的使用也是通过下标的方式
4.二维数组在内存中的存储
二维数组在内存中也是连续存储的
5.数组的越界
数组的下标是有范围限制的。数组的下规定是从 0 开始的,如果数组有 n 个元素,最后一个元素的下标就是 n-1 。所以数组的下标如果小于 0 ,或者大于 n-1 ,就是数组越界访问了,超出了数组合法空间的访问。C 语言本身是不做数组下标的越界检查,编译器也不一定报错,但是编译器不报错,并不意味着程序就是正确的
#include <stdio.h>
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
int i = 0;
for(i=0; i<=10; i++) //最大i小于10
{
printf("%d\n", arr[i]);//当i等于10的时候,越界访问了
}
return 0;
}
4.数组作为函数的参数
void bubble_sort(int arr[], int sz)//参数接收数组元素个数
{
}
int main()
{
int arr[] = {3,1,7,5,8,9,0,2,4,6};
int sz = sizeof(arr)/sizeof(arr[0]);
bubble_sort(arr, sz);
for(i=0; i<sz; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
当数组传参的时候,实际上只是把数组的首元素的地址传递过去了。所以即使在函数参数部分写成数组的形式: int arr[] 表示的依然是一个指针: int *arr 。那么,函数内部的 sizeof(arr) 结果是 4 。
5.数组名
数组名通常情况下就是数组首元素的地址