目录
一.一维数组的创建
1.数组的基本形式
2.变长数组
3.数组的初始化
二.数组的本质
三.一维数组的使用
1.访问数组成员
2.计算数组的大小
四.一维数组在内存中的存储
五.二维数组
1.二维数组的形式
2.二维数组的初始化规则
六.二维数组的使用
1.打印二维数组
七.二维数组在内存中的存储
八.数组越界的情况
九.数组名要点
1.数组名是首元素的地址(存在两个例外)
2.arr,&arr[0],&arr的区别(以及它们+1后的含义)
十.打印数组的两种写法
法一:利用下标引用操作符[](元素本身)
法二:解引用首元素地址(数组名/p)
小拓展:加法交换律的写法
十一.数组作为函数参数时
1.传参的两种形式
1.数组在传参的时候会发生数组名的降级(冒泡排序演示)
一:无法排序的情况
二:解决方式:别在函数内部求数组的个数
十二.数组的实际应用:三子棋
一.一维数组的创建
1.数组的基本形式
2.变长数组
- C99中引入了变长数组的概念
- 变长数组支持数组的大小使用变量来指定,但是变长数组不能初始化
- 变长数组不是数组的长度可以变化
例:
int n=0; scanf("%d",&n); int arr[n];支持C99标准的编译器环境下能编译
3.数组的初始化
- 数组可以不给定范围,但是一定要初始化!
- 初始化分为完全初始化,不完全初始化(除了初始化的元素,其余默认为0)
int arr1[2]={1,1};完全初始化 int arr2[10]={1}不完全初始化,第一个元素初始化为1,其余剩下都为0
二.数组的本质
- 数组的本质是一类相同元素的集合
例:
区别:
三.一维数组的使用
1.访问数组成员
- 数组是使用下标(下标引用操作符)来访问的,下标从0开始
- 数组的下标总是比个数小一位
例:
2.计算数组的大小
四.一维数组在内存中的存储
- 一维数组在内存中的存储是连续存放的
- 随着数组下标的增长,地址也是从低到高变化的
- 每一个内存单元大小就是一个字节(byte),即(int占4个内存单元)
图示:
五.二维数组
1.二维数组的形式
2.二维数组的初始化规则
- 放满一行,再来一行,其余初始化为0
- { } 决定换行
int arr[3][4]={{1,2},{4,5}};
- 二维数组,行有几个可以不知道,列有几个必须知道
int arr[][4]={{1,2},{4,5}};
六.二维数组的使用
- 二维数组的使用也是通过下标的方式
图示:
1.打印二维数组
七.二维数组在内存中的存储
- 二维数组在内存中的储存也是连续存放的
- 随着数组下标的增长,地址也是从低到高变化的
PS:引申用法:当把每行当作一维数组时,数组名可视作行名
图示:
八.数组越界的情况
- 数组的下标有范围限制。数组的规定是从0开始,如果数组有n个元素,最后一个元素的下标就是n-1。如果数组的下标小于0或者大于n-1,数组越界访问。
- C语言本身不做数组下标的越界检查,编译器不一定报错
九.数组名要点
1.数组名是首元素的地址(存在两个例外)
- sizeof(arr),数组名表示整个数组,计算的是整个数组的大小
- &arr,数组名表示整个数组,取出的是整个数组的地址
除此之外,遇到的数组名都是数组首元素的地址
2.arr,&arr[0],&arr的区别(以及它们+1后的含义)
- arr与&arr[0]等效,表示首元素的地址
- &arr表示数组的地址
PS:arr[n]表示第n+1个数组元素
代码演示:
int arr[10]={0}; printf("%p\n",arr);首元素的地址 printf("%p\n",arr+1);首元素的地址+1 printf("%p\n",&arr[0]);首元素的地址 printf("%p\n",&arr[0]+1);首元素的地址+1 printf("%p\n",&arr);数组的地址 printf("%p\n",&arr+1);数组结尾下一个的地址
十.打印数组的两种写法
int arr[10]={1,2,3,4,5,6,7,8,9,10}; int*p=&arr[0]; p为首元素地址 int*p=arr;
法一:利用下标引用操作符[](元素本身)
for(int i=0;i<10;i++) { printf("%d",arr[i]); }
法二:解引用首元素地址(数组名/p)
//int*p=&arr[0]; p为首元素地址 for(int i=0;i<10;i++) { printf("%d",*(p+i)); printf("%d",*(arr+i)); }
原理图示:
小拓展:加法交换律的写法
- arr[i]等效于i[arr]
int arr[10]={1,2,3,4,5,6,7,8,9,10}; for(int i=0;i<10;i++) { printf("%d",arr[i]); arr[i]--->*(arr+i)---->*(i+arr) printf("%d",i[arr]) }
十一.数组作为函数参数时
1.传参的两种形式
二者等效:
void bubble_sort(int* arr); void bubble_sort(int arr[10]);
1.数组在传参的时候会发生数组名的降级(冒泡排序演示)
一:无法排序的情况
void bubble_sort(int arr[10]) { //求数组的元素个数 int sz=sizeof(arr)/sizeof(arr[0]); 问题点:此时的arr不再是数组,已经降级 //冒泡排序的趟数 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]; arr[j]=arr[j+1]; arr[j+1]=tmp; } } } } int main() { int arr[]={3,1,7,5,8,9,0,2,4,6}; bubble_sort(arr); for(i=0;i<sizeof(arr)/sizeof(arr[0]);i++) { printf("%d",arr[i]); } return 0; }
二:解决方式:别在函数内部求数组的个数
void bubble_sort(int arr[10]) { //冒泡排序的趟数 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]; arr[j]=arr[j+1]; arr[j+1]=tmp; } } } } int main() { int arr[]={3,1,7,5,8,9,0,2,4,6}; bubble_sort(arr); //求数组的元素个数 int sz=sizeof(arr)/sizeof(arr[0]); 改变点:此时arr为数组 for(i=0;i<sizeof(arr)/sizeof(arr[0]);i++) { printf("%d",arr[i]); } return 0; }
十二.数组的实际应用:三子棋
后续更新