1.一维数组的创建和初始化
int main()
{
// int arr1[10];
int n = 0;
scanf("%d",&n);
//int count = 10;
int arr2[n]; //局部的变量,这些局部的变量或者数组是存放在栈区的,存放在栈区上的数组,如果不初始化的话,默认是随机值
// VS2019 VS2022 这样的IDE 不支持C99种的变长数组
//C99 标准之前,数组的大小只能是常量表达式
//C99 标准中引入了:变长数组的概念,使得数组在创建的时候可以使用变量,但是这样的数组不能初始化
int i = 0;
for(i=0;i<n;i++)
{
printf("%d\n", arr2[i]);
}
// char arr3[10];
// float arrt[10];
// double arr5[20];
return 0;
}
//数组的初始化
//数组的初始化上指,在创建数组的同时给数组的内容一些合理初始值(初始化)
int main()
{
// int arr1[10] = {1,2,3,4,5,6,7,8,9,10}; //完全初始化
// int arr2[10] = {1,2,3}; //不完全初始化
// int arr4[10] = {0};//不完全初始化,剩余的元素默认都是0
// int arr3[] = {}; //省略数组大小,数组必须初始化,数组的大小上根据初始化内容来定的
// int arr5[] = {1,2,3};
// //int arr6[]; //err
char arr[] = "abc"; // a b c \0
char arr2[] = {'a','b','c'}; // a b c
char arr3[] = {'a',98,'c'}; // a 98=b c
return 0;
}
2.一维数组的使用
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
// 0,1,2,3,4,5,6,7,8,9
//printf("%d\n",arr[5]); //[]下标引用操作符
//printf("%d\n",arr[0]); //[]下标引用操作符
int i = 0;
int sz = sizeof(arr) / sizeof(arr[0]); //计算数组大小
for(i = 0;i<sz;i++)
{
scanf("%d",&arr[i]);
}
for(i = 0;i<sz;i++)
//for(i=0;i < sz;i += 2)
//for(i = sz; i>=0; i--)
{
printf("%d\n",arr[i]);
}
return 0;
}
int main()
{
int arr[10] = {}; //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;
}
3.一维数组在内存中的存储
//一维数组在内存中存储
int main()
{
int arr[10] = {1,2,3,4,5};
int sz = sizeof(arr) / sizeof(arr[0]);
int i =0;
for(i = 0;i < sz;i++)
{
printf("&arr[%d] = %p\n",i,&arr[i]);
}
return 0;
}
4.二维数组的创建和初始化
//二维数组
// int main()
// {
// //数组创建
// int arr[3][4]; //3行4列数组
// char ch[3][8];
// //数组初始化
// int arr1[3][4] = {{1,2,3,4},{2,3,4,5},{3,4,5,6}};
// int arr2[3][4] = {1,2,3,4,2,3,4,5,3,4,5,6};//每一行放满,再放剩下的
// //二维数组初始化,行可以省略,但是列不能省略
// int arr3[3][4] = {{1,2,3},2,3,4,5,3,4,5,6};
// //printf("%d\n",&arr[0]);
// return 0;
// }
5.二维数组的使用
int main()
{
int arr[4][5] = {{1,2,3,4,5},{2,3,4,5,6},{3,4,5,6,7},{5,6,7,8,9}};
//二维数组的行和列都是从0开始的
//printf("%d\n", arr[2][3]); //6
int i = 0;
//行号
for(i = 0;i<4;i++)
{
int j= 0;
for(j = 0;j<5; j++)
{
printf("%d ",arr[i][j]); // 0 1 2 3 4
}
printf("\n");
}
return 0;
}
6.二维数组在内存中的存储
//二维数组在内存中的存储
int main()
{
int arr[4][5] = {{1,2,3,4,5},{2,3,4,5,6},{3,4,5,6,7},{5,6,7,8,9}};
//二维数组的行和列都是从0开始的
//printf("%d\n", arr[2][3]); //6
int i = 0;
//行号
for(i = 0;i<4;i++)
{
int j= 0;
for(j = 0;j<5; j++)
{
//printf("%d ",arr[i][j]); // 0 1 2 3 4
printf("&arr[%d][%d] = %p\n",i,j,&arr[i][j]); //二维数组在内存中也是连续存放的
}
printf("\n");
}
return 0;
}
7.数组越界
数组的下标是有范围限制的
数组的下规定是从0开始的,如果数组有n个元素,最后一个元素的下标就是n-1
所以数组的下标如果小于0,或者大于n-1,就是数组越界访问了,超出了数组合法空间的访问
C语言本身是不做数组下标的越界检查,编译器也不一定报错,但是编译器不报错,并不意味着程序就是正确的,我们自己要做好越界的检查
//数组越界
//二维数组的行和列有可能也会越界
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
int i = 0;
for(i=0;i<=10;i++) //1 2 3 4 5 6 7 8 9 10 1213399056 % 越界访问
//for(i=0;i<10;i++) //1,2,3,4,5,6,7,8,9,10
{
printf("%d ",arr[i]);
}
return 0;
}
8.数组作为函数参数
我们会将数组作为参数传个函数,比如我们实现一个冒泡排序
//数组作为函数参数
//输入10个整数,对这组数进行排序
//排序方法: 冒泡排序,选择排序,插入排序,快速排序
//void bubble_sort(int arr[10],int sz) //这里的arr的本质是指针变量
void bubble_sort(int* arr,int sz)
{
int i = 0;
// 4 / 4 = 1
//int sz = sizeof(arr) / sizeof(arr[0]); // sz = 1
for( i = 0;i < sz-1;i++)
{
int j = 0;
//每一趟开始前就假设已经有序了
int flag = 1;
//一趟每部比较多对数
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;
flag = 0;
}
}
if(flag == 1)
{
break;
}
}
}
int main()
{
int arr[10] = {0};
//输入
int i = 0;
int sz = sizeof(arr) / sizeof(arr[0]);
for(i = 0;i< sz; i++)
{
scanf("%d",&arr[i]);
}
//冒泡排序 - 两两相邻的元素尽量比较
//排序-升序
//让这个函数来完成数组arr中数据的排序
bubble_sort(arr,sz); //arr 是数组首元素的地址
//arr作为数组传参,传递的是地址
//趟数
// 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;
// }
// }
// }
//输出
for( i = 0; i < sz;i++)
{
printf("%d ",arr[i]);
}
return 0;
}
//数组名该怎么理解?
//数组名通常情况下就是数组首元素的地址
//但是有2个例外 1.sizeof(数组名),数组名单独放在sizeof()内部,这里的数组名表示整个数组,计算的是整个数组的大小
//2. &数组名,这里的数组名也表示整个数组,这里取出的是整个数组的地址
//除此指之外,遇到的数组名都表示数组首元素地址
// int main()
// {
// int arr[10] = {1,2,3,4,5,6};
// printf("%p\n",arr); //0x16b567340
// printf("%p\n",arr+1); //0x16b57f344
// printf("%p\n",&arr[0]); //0x16b567340
// printf("%p\n",&arr[0]+1); //0x16b57f344
// //printf("%d\n",sizeof(arr)); // 40
// printf("%p\n",&arr); //0x16b567340 数组的地址
// printf("%p\n",&arr+1); //0x16b57f368 +1 跳过整个数组
// return 0;
// }