一.一维数组

1.一维数组的定义

(1)格式

① 方式一

与Java存在细微差异

格式:数据类型 数组名[数组长度];

例子:int arr[10];

② 方式二

定义数组的同时存入数据

Tip:

  • 下面的定义方法中,数组的长度可以省略,此时会根据大括号内数据的个数,自动确定长度
  • 如果定义了长度,但大括号里面填入的数据不足以填满数组,其余位置的默认值是0

格式:数据类型 数组名[数组长度] = {data1,data2,data3...};

例子:int arr[] = {10, 20, 30};

③ 方式三

定义数组时在指定索引存入数据

1.规则和方式二类似,这里的数组长度以最大自定义存储数据的索引为准

  • 例如,自定义索引中最大值为7,那么数组的长度将被设置为8.

2.方式三可以与方式二混合使用

  • int arr[15] = {1, [5] = 10, 11, [10] = 20, 21};,索引0、5、6、10、11的位置被赋值

格式:数据类型 数组名[数组长度] = {[索引1] = data1,[索引2] = data2...};

例子:int arr[15] = {[5] = 10,[10] = 20};索引5和10被赋值了,数组长度为11,其余位置数据为0

2.数据元素的调用

(1)格式

格式:数组名[索引]

例子:int score = arr[0];

(2)关于数组索引越界⭐

在C语言中,对于数组索引越界是不会进行检查的,意味着编译器不一定会报错。

3.数组长度

在C语言中,数组的长度不是直接表示的。数组的长度是在定义数组时确定的,并且存储在编译器中,而不是在运行时存储在数组对象中。因此,不能直接通过数组来获取其长度。

(1)获取数组长度

需要在运行时获取数组的长度,可以使用sizeof运算符配合数组,间接的计算数组的长度

① 大致实现

其依旧大致就是数组成员都是同一类型的,每个成员的字节长度都一样,只要用数组的字节长度除于成员的字节长度,就可以得到数组的长度了

1.利用sizeof获取数组的字节长度(字节大小)

2.利用sizeof获取数组中单个原始占用的字节长度(字节大小)

3.用数组的字节长度除于单个元素的字节长度,就可以的到当前数组的元素数量即数组长度了

② 例子
int main() {
    int a[10];
    int arrL = sizeof(a);
    int data = sizeof(a[0]);
    printf("当前数组的字节长度:%d", arrL);
    printf("当前数组单个元素的字节长度:%d", data);
    //将上面获取到的数组长度与其单个元素相除,就可以得到数组中元素的个数,即数组的长度了
    printf("当前数组的长度%d \n", arrL / data);

    return 0;
}

4.数组的遍历

和Java类似,不过就是表示数组长度的那部分相对复杂,要用上面那个方式去表示

Idea的快捷指令:数组名.for

int main() {

    int arr[10];
    
    //给数组中的每个元素赋值
    for (int i = 0; i < sizeof(arr)/sizeof(int); i++) { //对数组元素arr[0]~arr[9]赋值
        arr[i] = i;
    }
    //遍历数组中的元素
    printf("遍历数组中的元素:\n");
    for (int i = 0; i < sizeof(arr)/sizeof(int); i++) { //输出arr[0]~arr[9]共10个数组元素
        printf("%d ", arr[i]);
    }
    printf("\n");
    return 0;
}

5.一位数组内存分析

相较于Java对于内存更加强调了,Java中的数组也是类似的内存分布,但因为不用手动管理,所以之前没有强调。

(1) 内存图

针对如下代码

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

对应的内存结构:

1.数组名所代表的地址值其实是该数组第一个元素的地址值

2.C语言中数组的每个元素都是有独立的地址的,每个元素以其首地址作为自己的地址值。

  • 数组名:记录该数组的首地址,即a[0]的地址,作为当前数组的地址

  • 数组的各个元素是连续分布的

    • 下一个地址值一般就是:当前地址值+当前数据类型所占的字节数

    • 假如 a[0] 地址是0x1122,则a[1]地址= a[0]的地址+int字节数(4) = 0x1122 + 4 = 0x1126,后面 a[2] 地址 = a[1]地址 + int 字节数(4) = 0x1126 + 4 = 0x112A,依次类推...

image-20230811192849889

(2)变长数组

变长数组时在C99标准中被引入,在C11标准中被标记为可选特性。某些编译器可能不支持变长数组,或者可能有特定的限制和行为。

数组声明的时候,数组长度除了使用常量,也可以使用变量或表达式来指定数组的大小。这叫做变长数组(variable-length array,简称 VLA)。

特征: 数组的长度只有运行时才确定

好处: 使得不必在开发阶段随意的估计数组长度,而是交由程序运行时为数组分配精确的长度

① 实现
Ⅰ.通过变量作为数组长度

任何长度需要运行时才能确定的数组,都是变长数组。比如,

int i = 10;
int a1[i];
int a2[i + 5];
int a3[i + k];
Ⅱ.通过动态内存分配来实现

如果你的编译器版本不支持变长数组,还可以考虑使用动态内存分配(使用malloc()函数 )来创建动态大小的数组。

分配:

int length = 5;
int *arr = (int *)malloc(length * sizeof(int));

释放:

**注:**使用完动态内存创建数组后,一定要回收此数组的内存空间,否则,就会发生内存泄漏的问题

free(arr);

6.一维数组的应用

(1)数组的赋值

① 循环赋值
Ⅰ.优缺点

**优点:**不用引入头文件,IDEA直接代码提示

**缺点:**代码量太大,如果需要遍历多个数组,略显繁琐

Ⅱ.实现

就是Java那一套,很熟了,不赘述

通过for循环,循环遍历数组内的元素,并逐一复制给新的数组

Ⅲ.代码演示
#include 

#define LENGTH 3

int main() {
    int a[LENGTH] = {10, 20, 30};
    int b[LENGTH];

    // 复制数组 a 到数组 b
    for (int i = 0; i < LENGTH; i++) {
        b[i] = a[i];
    }

    // 打印数组 b 的内容
    printf("复制后的数组 b:");
    for (int i = 0; i < LENGTH; i++) {
        printf("%d ", b[i]);
    }
    printf("\n");

    return 0;
}
② memcy()函数复制

memcpy() 函数定义在头文件 string.h 中,直接把数组所在的那一段内存,再复制一份。

Ⅰ.优缺点

**优点:**更加高效,代码小

**缺点:**需要引入头文件,引入前IDEA不会有代码提示

Ⅱ.使用

头文件:string.h

函数参数:

  • 目标数组
  • 源数组
  • 要复制的字节数:源数组长度 * 源数组数据类型占内存的字节
    • 例如:int a[LENGTH] = {10, 20, 30};,就是3 * sizeof(int)
Ⅲ.代码示例
#include 
#include 

#define LENGTH 3

int main() {
    int a[LENGTH] = {10, 20, 30};
    int b[LENGTH];

    // 使用 memcpy 函数复制数组 a 到数组 b
    memcpy(b, a, LENGTH * sizeof(int));

    // 打印数组 b 的内容
    printf("复制后的数组 b:");
    for (int i = 0; i < LENGTH; i++) {
        printf("%d ", b[i]);
    }
    printf("\n");

    return 0;
}

(2)数组的反转

固有思维是再定义一个数组来配合反转,但这个不可取,尽量采取下面的两个

① 方式一
Ⅰ.实现思想

思想: 数组对称位置的元素互换

实现:

image-20221117195931777

使用循环进行遍历,遍历的长度是数组中间,因为到中间刚好两侧数据都实现替换了

让数据1和数据2两者交换数据

  • **数据1:**从起点向后走
  • **数据2:**从终点向前走
Ⅱ.代码演示
int main() {
    int arr[] = {1,2,3,4,5,6,7,8,9};
    int size = sizeof(arr) / sizeof(arr[0]); //数组的长度

    printf("原始数组:");
    for (int i = 0; i < size; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");

    //主要业务代码
    for(int i = 0;i < size / 2;i++){
        //将arr[i]的值赋值给temp临时存储
        int temp = arr[i];
        //使前面的元素和后面的元素交换数据
        arr[i] = arr[size - 1 - i];
        //再通过temp将前面的元素的数据交给后面的元素
        arr[size - 1 - i] = temp;
        //至此,前后两个对称元素的数据交换完成
    }

    printf("反转后的数组:");
    for (int i = 0; i < size; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");

    return 0;
}
② 方式二

整体就代码来看和第一种差不到,就是将原本比较复杂的式子用变量替换了

Ⅰ.示意图:

1688562327054

Ⅱ.代码演示
int main() {
    int arr[] = {1, 2, 3, 4, 5,6,7,8,9};
    int size = sizeof(arr) / sizeof(arr[0]); //数组的长度

    printf("原始数组:");
    for (int i = 0; i < size; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");

    int left = 0; // 起始指针
    int right = size - 1; // 结尾指针

    while (left < right) {
        // 交换起始指针和结尾指针指向的元素
        int temp = arr[left];
        arr[left] = arr[right];
        arr[right] = temp;

        // 更新指针位置
        left++;
        right--;
    }

    printf("反转后的数组:");
    for (int i = 0; i < size; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");

    return 0;
}

7.Char数组与字符串

(1)char数组

顾名思义,就是指数组元素的数据类型为字符类型的数组

(2)字符串⭐

Java中字符串存储的底层也是一个字符输出,只不过在Java中对其进行了封装,封装成String类了而已,这点从Sting具有索引便可略窥一二。

1.在C语言中,字符串通常被表示为一个字符数组,其中每个字符都是一个字节其结束必须以一个空字符(\0)标记,这是一个特殊的字符,其ASCII值为0,标记其是一个字符串

2.C语言中字符串的空位通常用\0(空字符)来填充

① 字符串的写法
Ⅰ.标准写法

就是用写字符数组的方式对字符串进行书写,然后在其后面再加一个\0标记其是一个字符串

**缺点:**过于繁琐

//显式以'\0'为最后一个字符元素结束
char str[] = {'h','e','l','l','o',' ','w','o','r','l','d','\0'};
Ⅱ.简化写法

直接定义字符数组,然后指向两个双引号包裹的字符串。

优点:

  • 书写简单
  • \0标识符不用自己书写,C语言自动添加
char str[] = "hello world";
② 字符串对应数组的长度
Ⅰ.概述

对应的存储为:

1689220044896

字符串对应数组每个字符占用1个字节,其长度是要包含标记符号\0的,占一个字节,也包含空格,同样占一个字节。

Ⅱ.例子:

**示例一:**其字符数组长度是6

**示例二:**其字符数组长度是50(有标识以标识为准)

char s1[] = "hello"; //示例一
char s1[50] = "hello"; //示例二
③ 字符串长度
Ⅰ.概述

单纯字符串的长度是不包含\0的,其长度就是其本身具有的字符数。

Ⅱ.获取长度的函数

**函数:**Strlen(参数)

头文件:Sting.h

  • 参数:字符串对应的字符数组

示例:

#include 
#include     //需要加载此头文件

int main() {
    char nation[10] = "China";
    printf("%d\n", strlen(nation));     //5
}
Ⅲ.示例

**示例一:**其字符长度是5

**示例二:**其字符长度是5

char s1[] = "hello"; //示例一
char s1[50] = "hello"; //示例二
最后修改:2024 年 03 月 11 日
如果觉得我的文章对你有用,请随意赞赏