当前位置: 首页 > news >正文

数组理论基础

一维数组

数组是计算机科学中最基本的数据结构之一

数组的概念:存放在连续内存空间上的相同类型数据的集合

【eg.】将10个整型数据1-10存放在数组arr中

int arr[10] = {1,2,3,4,5,6,7,8,9,10};

每个数组元素都有下标,下标都是从 0 开始

使用下标来访问数组中的每个元素,eg. arr[0] 对应数组的第一个元素

一维数组的创建和初始化

数组的创建

一维数组的创建方式如下:

type_t arr_name [const_n];
//type_t 是指数组的元素类型
//arr_name 是数组名
//const_n 是一个常量表达式,用于指定数组的大小

下面例举一些数组创建的实例:

//代码1
int arr1[10];//代码2 <🚩错误示例>
int count = 10;		//count是变量
int arr2[count];	//[]中需要的是常量表达式//代码3
char arr3[10];
float arr4[1];
double arr5[20];

注意】数组创建,[] 中要给常量才可以,不能使用变量(如果支持C99,那么可以使用变量,即创建变长数组)

数组的初始化

数组的初始化是指在创建数组的同时给数组元素赋初始值(初始化)

初始化分为完全初始化不完全初始化,下面举例说明:

  • 完全初始化

    int arr[10] = {1,2,3,4,5,6,7,8,9,10};
    

    在这里插入图片描述

  • 不完全初始化

    int arr[10] = {1,2,3,4,5};
    

    在这里插入图片描述

    没有赋值的元素默认为 0

下面例举一些数组初始化的实例:

int arr1[10] = {1,2,3};
int arr2[] = {1,2,3,4,5};
int arr3[5] = {1,2,3,4,5};	//arr2 和 arr3 是一样的效果
char arr4[3] = {'a',98,'c'};
char arr5[] = {'a','b','c'}; //这个数组的长度是3,但是求得的字符串长度是随机值,因为字符串以'\0'为结束标志
char arr6[] = "abc";	//用数组表示字符串,数组元素是:a b c \0 (一共4个元素,注意和 arr5 区分)
char arr7[5] = "abc";	//数组元素是:a b c \0 \0

一维数组的使用

操作符:[] 是下标引用操作符,就是数组访问的操作符

#include <stdio.h>
int main(){int arr[10] = {0};	//数组不完全初始化//计算数组的元素个数int sz = sizeof(arr)/sizeof(arr[0]);//对数组元素赋值(数组是使用下标来访问的,下标从 0 开始)for(int i = 0;i < 10;i++){arr[i] = i;}//输出数组内容for(int i = 0;i < 10;i++){printf("%d ",arr[i]);}return 0;
}

总结

  • 数组是使用下标来访问的,下标是从0开始的
  • 数组大小可以通过计算得到

一维数组在内存中的存储

#include <stdio.h>int main() {int arr[10] = {0};int i = 0;for (i = 0; i < 10; i++) {printf("&arr[%d] = %p\n", i, &arr[i]);// %p :按地址的格式打印 —— 十六进制的打印}return 0;
}

在这里插入图片描述

总结

  1. 一维数组在内存中是连续存放的
  2. 随着数组下标的增长,地址是由低到高变化的

因为数组是连续存储的,所以当我们知道数组的首元素地址时,就可以找到数组中所有的元素

#include <stdio.h>int main() {int arr[10] = {1,2,3,4,5,6,7,8,9,10};int* p = arr; //数组名是数组首元素的地址//让指针 p 指向数组 arr 的第一个元素,也就是 &arr[0]int i = 0;for (i = 0; i < 10; i++) {printf("%d\n", *p);	//*p 表示 “取出 p 所指向地址中的值”(解引用)p++;	//指针移动到下一个 int 元素}return 0;
}//输出:
1 2 3 4 5 6 7 8 9 10

二维数组

C语言提供了类似矩阵 多维数组

【二维数组可以看作是一维数组,数组中的每个元素也是数组】

二维数组的创建和初始化

二维数组的创建

int arr1[3][4];
char arr2[3][5];
double arr3[2][4];

二维数组的初始化

int arr1[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};	//完全初始化

在这里插入图片描述

int arr2[3][4] = {1,2,3,4,5,6,7};	//不完全初始化,未赋值部分补0

在这里插入图片描述

int arr3[3][4] = { {1,2},{3,4},{5,6} };		//一行一行地初始化

在这里插入图片描述

【注意】二维数组初始化时行数可以省略,但是列数不可以省略

int arr4[][4] = { {1,2},{3,4},{5,6} };

二维数组的使用

二维数组的使用也是通过下标的方式

#include <stdio.h>int main() {int arr[3][4] = { {1,2},{3,4},{5,6} };int i = 0;int j = 0;for(i = 0; i < 3; i++){for(j = 0; j < 4; j++){printf("%d ",arr[i][j]);}printf("\n");}return 0;
}//输出:
1 2 0 0
3 4 0 0
5 6 0 0

二维数组在内存中的存储

#include <stdio.h>int main() {int arr[3][4] = { {1,2},{3,4},{5,6} };int i = 0;int j = 0;for(i = 0; i < 3; i++){for(j = 0; j < 4; j++){printf("&arr[%d][%d] = %p\n", i, j, &arr[i][j]);}}return 0;
}

在这里插入图片描述

总结二维数组在内存中也是连续存放的,每一行内部是连续的,行与行之间也是连续的

数组作为函数参数

在很多时候需要将数组作为函数参数传递,比如:冒泡排序函数将一个整型数组排序

冒泡排序函数的错误设计

//方法1
#include <stdio.h>void bubble_sort(int arr[]){	//形参 arr 本质上是指针,是数组首元素地址//计算数组元素个数,确定冒泡排序趟数int sz = sizeof(arr)/sizeof(arr[0]);	//🚩 错误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};	//需要将数组排序为升序bubble_sort(arr);return 0;
}

修正:

#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};	//需要将数组排序为升序int sz = sizeof(arr)/sizeof(arr[0]);bubble_sort(arr,sz);return 0;
}

【注意】数组名是首元素地址

但是有两个例外情况:

  1. sizeof(数组名) — 数组名表示整个数组 — 计算的是整个数组的大小,单位是字节
  2. &数组名 — 数组名表示整个数组 — 取出的是整个数组的地址
#include <stdio.h>int main() {int arr[10] = { 0 };printf("%p\n", &arr);printf("%p\n", &arr+1);printf("%p\n", arr);printf("%p\n", arr+1);return 0;
}

在这里插入图片描述

相关文章:

  • AI Agent开发第34课-用最先进的图片向量BGE-VL实现“图搜图”-下
  • overlay 模块加载失败问题分析
  • 一文详解opencv-python环境搭建:Mac配置python的cv2开发环境
  • 按照三级缓存机制,在单片机中实现大文件10M级别以上文件读写、解析实现方法,基于LIBCSV库和fatfs进行实现
  • Spring MVC 核心注解与文件上传教程
  • LabVIEW数据采集与传感系统
  • 潞晨科技将暂停DeepSeek API服务,AI大模型技术红利普惠化与市场竞争白热化叠加,内卷恶果,开始显现!
  • 基础服务系列-Windows10 安装AnacondaJupyter
  • 随机深林算法是分类还是回归?
  • 搭建哨兵架构
  • 开发指南:构建结合数字孪生、大语言模型与知识图谱的智能设备日志分析及生产异常预警系统
  • 思科路由器做DNS服务器
  • 掌握Go空接口强大用途与隐藏陷阱
  • 边缘计算场景下的GPU虚拟化实践(基于vGPU的QoS保障与算力隔离方案)
  • 第39讲|决策树与作物分布建模:可解释的AI助力农业智能推演
  • 大数据组件学习之--Kafka 安装搭建
  • 开关电源实战(六)STM32数控电源BuckBoost
  • 14.QT-多元素控件|QListWidget|QTableWidget|QTreeWidget(C++)
  • 如何以特殊工艺攻克超薄电路板制造难题?
  • 高防服务器适合哪些行业使用
  • 中国戏剧奖梅花奖终评启动在即,17场演出公益票将发售
  • 第八届进博会将致力于打造“五个高”,为展商增值赋能
  • 钱理群|直面衰老与死亡
  • 朱雨玲:从前世界第一到兼职运动员,30岁后开始“玩”乒乓
  • 画廊主韦尔:是喜是伤的一生
  • 2025上海半马鸣枪,多个“首次”冲击一城双白金