数组理论基础

一维数组

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

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

【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;
}
相关推荐
hn小菜鸡6 小时前
LeetCode 377.组合总和IV
数据结构·算法·leetcode
懒惰的bit9 天前
STM32F103C8T6 学习笔记摘要(四)
笔记·stm32·学习
亮亮爱刷题10 天前
飞往大厂梦之算法提升-7
数据结构·算法·leetcode·动态规划
zkyqss10 天前
OVS Faucet练习(下)
linux·笔记·openstack
浦东新村轱天乐10 天前
【麻省理工】《how to speaking》笔记
笔记
奔跑的蜗牛AZ10 天前
TiDB 字符串行转列与 JSON 数据查询优化知识笔记
笔记·json·tidb
cwtlw10 天前
Excel学习03
笔记·学习·其他·excel
杭州杭州杭州10 天前
计算机网络笔记
笔记·计算机网络
zmuy10 天前
124. 二叉树中的最大路径和
数据结构·算法·leetcode
chao_78910 天前
滑动窗口题解——找到字符串中所有字母异位词【LeetCode】
数据结构·算法·leetcode