1.一维数组的创建和初始化
数组的创建
数组是一组相同类型元素的集合,数组就是存放一组数。数组的创建方式:
type_t arr_name[const_n]
type_t 是指数组的元素类型
const_n 是一个常量表达式,用来指定数组的大小
//代码1 int arr[10]; //代码2 int count = 10; //int arr2[count];//不能正常创建 //数组在创建时,[]中要给一个常量才可以,不能使用变量 //代码3 char arr3[10]; float arr4[1]; double arr5[20];
#include<stdio.h> int main() { int arr1[10];//创建一个类型为int 的数组,用来存放10个int类型的元素 char arr2[5];//创建一个类型为char 的数组,用来存放5个char类型的元素 int count = 10; //int arr3[count];// []内是常量表达式才可以 //VS2019 VS2022 这样的IDE(集成开发环境) 不支持C99 中的变长数组 //gcc是可以支持的 //C99 标准之前 数组的大小只能是常量表达式 //C99 标准中引入了 变长数组的概念,使得数组在创建的时侯可以使用变量,但是这样的数组不能初识化 return 0; }
数组的初识化
数组的初识化是指,在创建数组的同时给数组的内容一些合理的初始值(初始化)
int arr[10]={1,2,3); int arr2[]={1,2,3,4}; int arr3[5]={1,2,3,4,5}; char arr4[3]={'a',98,'c'}; char arr5[]={'a','b','c'}; char arr6[]="abcdef";
数组在创建的时候如果想不指定数组的大小就得初始化。数组的元素个数根据初始化的内容跟来确定。但是对于下面的代码要区分,内存中如何分配。
char arr1[]="abc"; //字符串 最后会默认加有'\0' char arr2[3]={'a','b','c'}; //只有abc 最后没有'\0'
#include<stdio.h> int main() { //数组在初始化是整体用大括号括起来,每个元素用逗号分隔开 int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };//完全初识化 int arr2[10] = { 1,2,3 };//不完全初始化 剩余元素默认为 0 int arr3[10] = { 0 };//不完全初识化 10个元素全是0 int arr4[] = { 0 };//省略数组大小,数组必须初始化,数组的大小是根据初识化的内容来确定的 这里只初始化1个,所以大小为1 int arr5[] = { 1,2,3 };//数组大小为3 //int arr6[];//错误写法 没有指定大小,也没有初始化 char arr7[] = "abc";//字符串,数组大小为4,因为最后有 '\0' char arr8[] = { 'a','b','c' };//数组大小为3 char arr9[] = { 'a',98,'c' };//与arr8数组相同,因为字符在存储时存放的时ASCII码值,b的ASCII码值是98 return 0; }
2.一维数组的使用
[ ]下标引用操作符,它其实就是数组访问的操作符。
#include<stdio.h> 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 //数组下标是从0开始的 数组使用下标来访问的 最后一个元素下标为数组元素个数减一 printf("%d\n", arr[5]); //6 [] 下标引用操作符 printf("%d\n", arr[0]); //1 [] 下标引用操作符 printf("%d\n", arr[3]); //4 [] 下标引用操作符 int i = 0; //数组的大小可以通过计算得到 //sizeof(arr)整个数组大小 sizeof(arr[0])一个元素大小 int sz = sizeof(arr) / sizeof(arr[0]);//数组的元素个数 for (i = 0; i < sz; i++)//循环 打印整个数组 { printf("%d ", arr[i]);//arr[i] i是变量 数组只是不能在创建时使用变量,访问时可以使用变量 } printf("\n"); for (i = 0; i < sz; i += 2)//循环 隔一个打印一个 i+=2 { printf("%d ", arr[i]); } printf("\n"); for (i = sz - 1; i >= 0; i--)//循环 逆序打印 { printf("%d ", arr[i]); } return 0; }
循环给数组赋值
#include<stdio.h> 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]);//通过循环 给数组每个元素赋值 } for (i = 0; i < sz; i++) { printf("%d ", arr[i]);//通过循环 打印每个数组元素 } return 0; }
sizeof 在数组中的使用
#include<stdio.h> int main() { int arr[10] = { 0 }; printf("%d\n", sizeof(arr));//40 计算的是数组的总大小 单位是字节 printf("%d\n", sizeof(arr[0]));//4 计算的是数组元素的大小 int 4 int sz = sizeof(arr) / sizeof(arr[0]);//计算数组元素的的个数 printf("%d\n", sz);//10 return 0; }
总结:
1.数组是使用下标来访问的,下标是从0开始的
2.数组的大小是可以通过计算得到的
3.一位数组在内存中的存储
#include<stdio.h> int main() { int arr[10] = { 1,2,3,4,5 }; int sz = sizeof(arr) / sizeof(arr[0]); int i = 0; for (i = 0; i < 10; i++) { //通过循环打印数组元素的地址 //会发现每相邻元素之间相差4 也是4个字节 //%p 用来打印16进制地址 &取地址 printf("&arr[%d] = %p\n", i, &arr[i]); } //可以得出结论 一维数组在内存中是连续存放的 return 0; }
仔细发现观察的结果,我们知道,随着数组下标的增长,元素的地址,也在有规律的递增,由此可以得出结论:数组在内存中是连续存放的,由低地址到高地址。
4.二维数组的创建和初始化
#include<stdio.h> int main() { //二维数组的创建 char arr[3][8];//3行8列 //数组初始化 int arr1[4][5] = { {1,2,3,4,5},{2,3,4,5,6},{3,4,5,6,7},{4,5,6,7,8} };//4行5列 //每一行再用{},分开 int arr2[4][5] = { 1,2,3,4,5,2,3,4,5,6,3,4,5,6,7,4,5,6,7,8 };//这种写法一行排满才放下一行。 int arr3[4][5] = { {1,2,3},{2,3,4},3,4,5,6,7,4,5,6,7 };//第一行和第二行指定只初识化前三个,后面的行排满换行 int arr4[4][5] = { {1,2,3},{2,3,4},{3,4,5,6,7},{4,5,6,7} };//没有赋值的默认为0 //二维数组初始化之后 //二维数组行可以省略,列不可以省略 int arr5[][5] = { {1,2,3},{2,3,4},{3,4,5,6,7},{4,5,6,7} }; return 0; }
注:二位数组下标的行和列都是从0开始的
5.二维数组的使用
#include<stdio.h> int main() { //初始化 int arr1[4][5] = { {1,2,3,4,5},{2,3,4,5,6},{3,4,5,6,7},{4,5,6,7,8} }; //打印 int i = 0; for (i = 0; i < 4; i++)//i是行号 { int j = 0; for (j = 0; j < 5; j++)//j是列号 { printf("%d ", arr1[i][j]);//利用循环 打印二维数组 } printf("\n"); } //二维数组在内存中的存储 //打印每个元素地址 for (i = 0; i < 4; i++) { int j = 0; for (j = 0; j < 5; j++) { printf("&arr1[%d][%d] = %p\n", i, j, &arr1[i][j]); } } //可以发现每个元素地址也是相隔4 即4个字节 int类型 //所以二维数组在内存中也是连续存放的 列不可省略是因为它们是连续的 return 0; } //自己理解 //二维数组是 一维数组 的数组 //数组名+行 是 列的数组名
内存图解
6.数组作为函数参数
首先我们先理解一下数组名的含义
#include<stdio.h> int main() { //数组名通常情况下就是数组首元素的地址 int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; printf("%d\n", arr); printf("%d\n", &arr[0]); //有两个例外 //1.sizeof(数组名) 数组名单独放在sizeof()内部,这里的数组名表示整个数组,计算的是整个数组的大小 printf("%d", sizeof(arr));//整个数组大小 10*4 = 40 //2.&数组名 这里的数组名也表示真个数组,这里取得是整个数组的大小 printf("%d\n", &arr);//数组首元素的地址也整个数组的地址数值上相同 //地址+1 是跳过一个元素 printf("%d\n", arr + 1); //地址加4 跳过一个元素 printf("%d\n", &arr[0] + 1); //地址加4 跳过一个元素 printf("%d\n", &arr + 1); //数组地址+1是跳过了这个数组 加了40 return 0; }
我们写一个函数来对一直数进行排序
#include<stdio.h> int bubble_sort(int arr[10], int sz)//可以把int arr[10]写成int *arr ,因为传入的是指针 { //数组传参传的是首元素地址 sizeof(arr)=4,因为arr是一个指针,只是数组首元素地址 大小为4 所以传入数组的元素个数sz //int sz = sizeof(arr) / sizeof(arr[0]);//1 //冒泡排序 //每趟确定一个最大数 for (int i = 0; i < sz - 1; i++) { //每一趟开始前假设数组已经有序 flag=0; int flag = 0; //一趟内部比较的对数 for (int j = 0; j < sz - 1 - i; j++) { if (arr[j] > arr[j + 1]) { //交换 int t = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = t; //交换说明没有顺序 int flag = 1;//改变flag } } if (flag == 0)//有序不再继续循环 { 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]); } //排序 - 升序 bubble_sort(arr,sz); for (i = 0; i < sz; i++) { printf("%d ", arr[i]); } return 0; }
谢谢观看,希望对大家学习有帮助