数组是一组相同类型元素的集合,男同女同狂喜!(不是
文章目录
前言
本篇笔记重点描述C语言中一维数组和二维数组的具体使用。
一、C语言中一维数组的创建和初始化
1.一维数组的创建
注:数组创建,在C99标准之前, [ ] 中要给一个常量才可以,不能使用变量。在C99标准支持了变长数 组的概念,数组的大小可以使用变量指定,但是数组不能初始化
type_t arr_name [const_n];
//type_t 是指数组的元素类型
//const_n 是一个常量表达式,用来指定数组的大小
//代码1
int arr1[10];
//即int为数组类型,数组里面的变量类型为int,arr1为数组名
//代码2
int count = 10;
int arr2[count];//数组时候可以正常创建?
//代码3
char arr3[10]; float arr4[1]; double arr5[20];
2.一维数组的初始化
数组的初始化和变量的初始化有细微的区别。
数组的初始化有两种:
1、普通初始化,如果想给数组初始化应该给一个{ }
2、完全初始化,如果[10]后面的{ }没给满10个数,那就是不完全初始化,后面会默认补\0
举个例子:
数组的普通初始化和完全初始化
int a = 10; //变量初始化
int arr[10] = {1,2,3,4,5,6,7,8,9,10}; //完全初始化
int arr[10] = {1,2,3,4}; //不完全初始化
//--------
int arr[5] = {1,2,3,4,5};
int arr2[ ] = {1,2,3,4,5};
//上面两串代码是完全等价的
注:如果[ ]没有指定大小的话,它会根据后面{ }内容来确定我们的数组初始化几个元素
3.一维数组的使用
[ ]是下标引用操作符。
数组的使用方式
#include <stdio.h>
int main(){
int arr[10] = { 0 };
arr [4] = 5;//[] - 下标引用符
int i = 0;
int sz = sizeof(arr) / sizeof(arr[0]);
//sizeof(arr)算的是整个数组的大小,算的是字节
//sizeof(arr[0])算的是第一个元素的大小。
//总大小除以第一个元素的大小就是元素的个数
for(i = 0; i < sz; i++){
printf(" %d " , arr[i]);
}
return 0;
}
4.一维数组在内存中的存储
数组在int类型中,每个元素都差4个字节,也就是说4个字节为一个元素。
1、一维数组在内存中是连续存放的!
2、随着数组下标的增长,地址是由低到高变化的!
3、数组名是数组首元素的地址!
4、整型数组是没有\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)
{
printf("&arr[%d] = %p\n", i, &arr[i]);
}
//输出结果为电脑内存的地址,而且每个都相隔4个字节
return 0;
}
二、C语言中二维数组的创建和初始化
1.二维数组的创建
二维数组和一维数组的创建只是形式上的不同而已。
//数组创建
int arr[3][4]; char arr[3][5]; double arr[2][4];
2.二维数组的初始化
二维数组的初始化,行可以省略,列不能省略。
//数组初始化
int arr[3][4] = {1,2,3,4};
int arr[3][4] = {{1,2},{4,5}};
int arr[][4] = {{2,3},{4,5}};
//二维数组如果有初始化,行可以省略,列不能省略
3.二维数组的使用
二维数组的使用也是和一维数组一样使用下标来使用。
另外需要注意的是,二维数组中第一行的行号是0,第一列列号是0。
#include <stdio.h>
int main() {
int arr[3][4];
int i = 0;
for(i=0; i<3; i++)
{
int j = 0;
for(j=0; j<4; j++)
{
printf("&arr[%d][%d] = %p\n", i, j,&arr[i][j]);
//%p - 是按地址的格式打印 - 十六进制的打印
}
}
return 0; }
} }
for(i=0; i<3; i++)
{
int j = 0;
for(j=0; j<4; j++)
{
printf("%d ", arr[i][j]);
}
}
return 0; }
%p - 是按地址的格式打印 - 十六进制的打印
4.二维数组在内存中的储存
二维数组在内存中的储存和一维数组一样,这里我们尝试打印二维数组的每个元素。
#include <stdio.h>
int main() {
int arr[3][4];
int i = 0;
for(i=0; i<3; i++){
int j = 0;
for(j=0; j<4; j++){
printf("&arr[%d][%d] = %p\n", i, j,&arr[i][j]);
}
}
return 0;
}
注:二维数组在内存中也是连续存放的!
一行内部连续,跨行也是连续的!
由此我们可知为什么行可以省略,列不能省略。因为计算机存储形式决定了,列起到划分区域的作用。
三、C语言中数组作为函数参数
某些场景,我们可能需要使用数组来作为参数传个函数,比如我们想实现一个冒泡排序函数(这里涉及了一些算法思想)
冒泡排序的思想:两两相邻的元素进行比较,并且可能的话需要交换。
1.冒泡排序函数的设计
#include <stdio.h>
void bubble_sort(int arr[])
{
//计算数组元素个数
int sz = sizeof(arr) / sizeof(arr[0]);//err
//确认躺数
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[] = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
//排序为升序 - 冒泡排序
bubble_sort(arr);
return 0;
}
以上代码其实是错误示范。
数组在传参的时候,传过去的其实是数组首元素的地址。
这里的形参arr本质是指针。(不能这样写)
正确代码应该在传参外面先计算好个数,再进行传参
#include <stdio.h>
void bubble_sort(int arr[], int sz)
{
//确认躺数
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[] = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
//排序为升序 - 冒泡排序
//计算数组元素个数
int sz = sizeof(arr) / sizeof(arr[0]);//err
bubble_sort(arr, sz);
return 0;
}
2.数组名是什么?
注:数组名就是首元素的地址!!!
#include <stdio.h>
int main() {
int arr[10] = {1,2,3,4,5};
printf("%p\n", arr); //数组名是首元素地址
printf("%p\n", &arr[0]);
printf("%d\n", *arr);
//输出结果
return 0; }
但是有两个例外!!!
1、sizeof(数组名) —数组名表示整个数组,计算的是整个数组的大小单位是字节。
2、&数组名 —数组名表示整个数组,取出的是整个数组的地址。
#include <stdio.h>
int main() {
int arr[ 10 ] = { 0 };
int sz = sizeof(arr); //数组名表示整个数组
printf("%d\n, sz");
//输出结果
return 0; }
同时,数组的地址+1和数组首元素地址+1有着本质的不同。
这里可以自己去尝试一下以下的代码
#include <stdio.h>
int main() {
int arr[ 10 ] = { 0 };
printf("%p\n, &arr");//输出数组的地址
printf("%p\n, &arr+1");//输出数组的地址+1
printf("%p\n, arr");//输出数组首元素地址
printf("%p\n, arr+1");//输出数组首元素地址+1
//+1前的输出结果是一样的,但是+1后的输出结果会完全不一样
return 0; }
总结
1、数组是一堆相同类型的元素的集合。
2、在数组初始化的时候如果在[ ]内没有指定大小,则会根据{ }的内容来确定数组初始化有几个元素。
3、数组在内存中是连续存放的,无论是一维数组还是二维数组
4、数组最重要的一个点,数组名就是首元素的地址!!!(这个很重要)
5、数组地址+1和数组首元素地址+1有着本质的不同,但一个同样的数组地址和数组首元素地址是相同的。