数组理论基础

一维数组

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

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

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

c 复制代码
int arr[10] = {1,2,3,4,5,6,7,8,9,10};

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

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

一维数组的创建和初始化

数组的创建

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

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

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

c 复制代码
//代码1
int arr1[10];

//代码2 <🚩错误示例>
int count = 10;		//count是变量
int arr2[count];	//[]中需要的是常量表达式

//代码3
char arr3[10];
float arr4[1];
double arr5[20];

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

数组的初始化

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

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

  • 完全初始化

    c 复制代码
    int arr[10] = {1,2,3,4,5,6,7,8,9,10};
  • 不完全初始化

    c 复制代码
    int arr[10] = {1,2,3,4,5};

    没有赋值的元素默认为 0

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

c 复制代码
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

一维数组的使用

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

c 复制代码
#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开始的
  • 数组大小可以通过计算得到

一维数组在内存中的存储

c 复制代码
#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. 随着数组下标的增长,地址是由低到高变化的

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

c 复制代码
#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语言提供了类似矩阵 多维数组

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

二维数组的创建和初始化

二维数组的创建

c 复制代码
int arr1[3][4];
char arr2[3][5];
double arr3[2][4];

二维数组的初始化

c 复制代码
int arr1[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};	//完全初始化
c 复制代码
int arr2[3][4] = {1,2,3,4,5,6,7};	//不完全初始化,未赋值部分补0
c 复制代码
int arr3[3][4] = { {1,2},{3,4},{5,6} };		//一行一行地初始化

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

c 复制代码
int arr4[][4] = { {1,2},{3,4},{5,6} };

二维数组的使用

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

c 复制代码
#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

二维数组在内存中的存储

c 复制代码
#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;
}

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

数组作为函数参数

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

冒泡排序函数的错误设计

c 复制代码
//方法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;
}

修正:

c 复制代码
#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. &数组名 --- 数组名表示整个数组 --- 取出的是整个数组的地址
c 复制代码
#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;
}
相关推荐
tod1139 分钟前
力扣高频 SQL 50 题阶段总结(四)
开发语言·数据库·sql·算法·leetcode
科技林总14 分钟前
使用Miniconda安装Jupyter
笔记
woodykissme1 小时前
倒圆角问题解决思路分享
笔记·学习·工艺
laplace01231 小时前
Clawdbot 部署到飞书(飞连)使用教程(完整版)
人工智能·笔记·agent·rag·clawdbot
iAkuya1 小时前
(leetcode)力扣100 57电话号码的字母组合(回溯)
算法·leetcode·深度优先
凉、介2 小时前
ACRN Hypervisor 简介
笔记·学习·虚拟化
历程里程碑2 小时前
Linux15 进程二
linux·运维·服务器·开发语言·数据结构·c++·笔记
dulu~dulu4 小时前
大英赛改错真题记录
笔记·英语·自用·英语改错
香芋Yu4 小时前
【机器学习教程】第03章:SVD与矩阵分解
笔记·机器学习·矩阵
EmbedLinX4 小时前
FreeRTOS 学习笔记
c语言·笔记·学习