C语言数组:数据的集合艺术(续)

前言
在上一篇文章中,我们深入探讨了C语言数组的基本概念、操作以及多维数组的应用。今天,我们将继续探索数组的更多高级特性,包括动态内存分配、指针与数组的关系以及数组在实际编程中的应用案例。
在这里插入图片描述

一、动态内存分配与数组

在C语言中,虽然数组的大小在定义时是固定的,但我们可以使用动态内存分配来改变数组的大小。这主要通过malloccallocrealloc等函数来实现。

malloc函数用于在堆上分配指定大小的内存,并返回指向该内存区域的指针。例如:

int *dynamicArray = (int *)malloc(10 * sizeof(int));
if (dynamicArray == NULL) {
    // 内存分配失败处理
}
// 使用dynamicArray...
free(dynamicArray); // 使用完毕后释放内存

在上述代码中,我们分配了一个包含10个整数的动态数组,并通过指针dynamicArray来访问和修改数组中的元素。需要注意的是,使用malloc分配的内存需要在使用完毕后通过free函数释放,以避免内存泄漏。

calloc函数与malloc类似,但它会初始化分配的内存为零。realloc函数则用于调整已分配内存的大小。

二、指针与数组的关系

在C语言中,数组名在大多数情况下会被解释为指向数组首元素的指针。这使得我们可以使用指针来访问和修改数组中的元素。

int numbers[5] = {1, 2, 3, 4, 5};
int *ptr = numbers; // ptr指向数组首元素
printf("%d\n", *(ptr + 2)); // 输出数组中的第三个元素:3

通过指针运算,我们可以灵活地访问数组中的任意元素。同时,指针也可以作为函数参数传递数组,使得函数能够操作数组而无需知道其大小。

然而,需要注意的是,指针和数组在类型上是有区别的。指针是一个变量,存储的是内存地址;而数组则是一系列相同类型元素的集合。因此,在使用时需要明确区分它们。

三、数组在实际编程中的应用

数组作为一种基础数据结构,在实际编程中有着广泛的应用。下面我们将通过几个示例来展示数组在不同场景下的使用。

示例1:统计字符串中字符出现的次数

#include <stdio.h>
#include <string.h>

#define MAX_CHAR 256 // 假设只处理ASCII字符

int main() {
    char str[] = "Hello, world!";
    int charCount[MAX_CHAR] = {0}; // 初始化字符计数器数组

    // 统计每个字符出现的次数
    for (int i = 0; i < strlen(str); i++) {
        charCount[(int)str[i]]++;
    }

    // 输出统计结果
    for (int i = 0; i < MAX_CHAR; i++) {
        if (charCount[i] > 0) {
            printf("'%c' appears %d times\n", (char)i, charCount[i]);
        }
    }

    return 0;
}

在上面的代码中,我们使用了一个大小为256的整数数组charCount来统计字符串中每个ASCII字符出现的次数。通过遍历字符串并增加对应字符的计数器,我们得到了每个字符的出现频率。
在这里插入图片描述

示例2:实现简单的排序算法

在之前的文章中,我们已经展示了如何使用数组实现冒泡排序算法。这里我们再给出一个使用数组实现选择排序算法的示例:

#include <stdio.h>

void selectionSort(int arr[], int n) {
    for (int i = 0; i < n - 1; i++) {
        int minIndex = i;
        for (int j = i + 1; j < n; j++) {
            if (arr[j] < arr[minIndex]) {
                minIndex = j;
            }
        }
        // 交换arr[i]和arr[minIndex]
        int temp = arr[i];
        arr[i] = arr[minIndex];
        arr[minIndex] = temp;
    }
}

int main() {
    int numbers[] = {64, 25, 12, 22, 11};
    int n = sizeof(numbers) / sizeof(numbers[0]);
    selectionSort(numbers, n);
    for (int i = 0; i < n; i++) {
        printf("%d ", numbers[i]);
    }
    printf("\n");
    return 0;
}

在上面的代码中,我们定义了一个selectionSort函数来实现选择排序算法。该函数接受一个整数数组和数组的大小作为参数,通过遍历数组并找到未排序部分中的最小元素,然后将其与未排序部分的第一个元素交换,从而完成排序。在main函数中,我们定义了一个待排序的整数数组,并调用selectionSort函数对其进行排序,最后输出排序后的结果。

示例3:使用数组实现简单的矩阵运算

数组还可以用于表示和操作矩阵,从而进行线性代数中的运算。下面是一个简单的示例,展示了如何使用二维数组实现矩阵的加法:

#include <stdio.h>

#define ROWS 3
#define COLS 3

void addMatrices(int a[][COLS], int b[][COLS], int result[][COLS]) {
    for (int i = 0; i < ROWS; i++) {
        for (int j = 0; j < COLS; j++) {
            result[i][j] = a[i][j] + b[i][j];
        }
    }
}

int main() {
    int matrixA[ROWS][COLS] = {
        {1, 2, 3},
        {4, 5, 6},
        {7, 8, 9}
    };
    int matrixB[ROWS][COLS] = {
        {9, 8, 7},
        {6, 5, 4},
        {3, 2, 1}
    };
    int result[ROWS][COLS];

    addMatrices(matrixA, matrixB, result);

    // 输出结果矩阵
    for (int i = 0; i < ROWS; i++) {
        for (int j = 0; j < COLS; j++) {
            printf("%d ", result[i][j]);
        }
        printf("\n");
    }

    return 0;
}

在上面的代码中,我们定义了一个addMatrices函数,它接受两个相同大小的二维数组作为输入,并将它们的对应元素相加,将结果存储在第三个二维数组中。在main函数中,我们定义了两个3x3的矩阵matrixAmatrixB,并调用addMatrices函数计算它们的和,最后输出结果矩阵。

四、结语

数组作为C语言中的一种基础数据结构,具有广泛的应用场景。通过掌握数组的定义、操作以及与其他编程概念(如指针、动态内存分配等)的结合使用,我们可以编写出高效且灵活的代码来处理各种数据集合。同时,在实际编程中,我们还需要注意数组的局限性和注意事项,以避免潜在的问题。

在本文中,我们深入探讨了数组与指针的关系、动态内存分配以及数组在实际编程中的应用案例。希望这些内容能够帮助你更全面地理解C语言中的数组,并在实际编程中灵活运用它们。在未来的学习和实践中,你还将继续发现数组的强大之处和更多高级用法。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/525312.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2024/4/2—力扣—不用加号的加法

代码实现&#xff1a; 思路&#xff1a;位运算&#xff0c;利用了异或和与的特性&#xff0c;异或操作与加操作的区别在于异或操作在二进制状态下两个数同1不进位&#xff0c;只是置为0&#xff0c;其他均相同&#xff0c;那么使用与运算计算进位值&#xff0c;补齐异或操作的缺…

算法 - 符号表-上

&#x1f3e0;个人主页&#xff1a;尘觉主页 文章目录 算法 - 符号表前言初级实现1. 链表实现无序符号表2. 二分查找实现有序符号表 二叉查找树1. get()2. put()3. 分析4. floor()5. rank()6. min()7. deleteMin()8. delete()9. keys()10. 分析 算法 - 符号表 前言 符号表&am…

Latex表格制作详细教程(table, tabular, multirow, multicolumn)

一、简单表格制作 Latex表格需要用到 table 和 tabular 环境。其中 table 环境里写表格的标题(caption&#xff09;、表格的位置之类的。 tabular 环境则是绘制表格的内容。一个简单的表格绘制代码如下所示&#xff1a; \documentclass{article}\begin{document}\begin{table…

怎么保证缓存与数据库的最终一致性?

目录 零.读数据的标准操作 一.Cache aside Patten--旁路模式 二.Read/Write Through Pattern--读写穿透 三.Write Back Pattern--写回 四.运用canal监听mysql的binlog实现缓存同步 零.读数据的标准操作 这里想说的是不管哪种模式读操作都是一样的&#xff0c;这是一种统一…

2 万字 42 道Java经典面试题总结(2024修订版)- Java集合篇

目录 1、Java中常用的集合有哪些&#xff1f;2、Collection 和 Collections 有什么区别&#xff1f;3、为什么集合类没有实现 Cloneable 和 Serializable 接口&#xff1f;4、数组和集合有什么本质区别&#xff1f;5、数组和集合如何选择&#xff1f;6、list与Set区别7、HashMa…

力扣刷题 102.二叉树的层序遍历

目录 题干 解题思路 总结与反思 题干 给你二叉树的根节点 root &#xff0c;返回其节点值的 层序遍历 。 &#xff08;即逐层地&#xff0c;从左到右访问所有节点&#xff09;。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;[[3],[9…

C语言——顺序表

文章目录 一、线性表二、顺序表顺序表和数组的区别顺序表的分类1.静态顺序表2.动态顺序表 三、动态顺序表的实现1.动态顺序表头文件2.动态顺序表源文件3.测试源文件 一、线性表 线性表&#xff08;linear list&#xff09;是n个具有相同特性的数据元素的有限序列。线性表是⼀种…

LeetCode-33. 搜索旋转排序数组【数组 二分查找】

LeetCode-33. 搜索旋转排序数组【数组 二分查找】 题目描述&#xff1a;解题思路一&#xff1a;二分查找。1.找哨兵节点&#xff08;nums[0]或nums[-1]&#xff09;可以确定nums[mid]位于前一段或后一段有序数组中。2. 就是边界left和right的变换&#xff0c;具体看代码。解题思…

阿里面试总结

ThreadLocal 线程变量存放在当前线程变量中&#xff0c;线程上下文中&#xff0c;set将变量添加到threadLocals变量中 Thread类中定义了两个ThreadLocalMap类型变量threadLocals、inheritableThreadLocals用来存储当前操作的ThreadLocal的引用及变量对象&#xff0c;把当前线程…

MySQL数据库版本为5.5.62,时间戳超出2038年1月19日的解决方案

MySQL数据库版本是 5.5.62&#xff0c;已设置字段的类型为BIGINT&#xff0c;使用FROM_UNIXTIME()函数来转换时间戳&#xff0c;返回NULL。 SELECT FROM_UNIXTIME(1617970800)SELECT FROM_UNIXTIME(2185743121)MySQL数据库版本为5.5.62&#xff0c;已设置字段的类型为BIGINT&a…

golang web 开发 —— gin 框架 (gorm 链接 mysql)

目录 1. 介绍 2. 环境 3. gin 3.1 gin提供的常见路由 3.2 gin的分组 main.go router.go 代码结构 3.3 gin 提供的Json方法 main.go route.go common.go user.go order.go 3.4 gin框架下如何获取传递来的参数 第一种是GET请求后面直接 /拼上传递的参数 第二种是…

Rust语言入门第一篇-环境搭建

Rust语言入门第一篇 Rust官网 一&#xff0c;环境搭建 1、C开发环境配置 Rust 语言的底层是依赖于 C/C 编译器的。在安装 Rust 编译器时&#xff0c;通常会自动安装所需的 C/C 编译环境&#xff0c;以便 Rust 能够生成可执行文件或库。因此&#xff0c;在安装 Rust 之前&…

用Vue全家桶手工搓了一个类似抖音短视频的软件,全开源

用Vue全家桶手工搓了一个类似抖音短视频的软件&#xff0c;全开源 软件简介 用Vue全家桶手工搓了一个高仿抖音&#xff0c;全开源 PC浏览器请用手机模式访问。先按F12调出控制台&#xff0c;再按CtrlShiftM切换到手机模式&#xff0c;手机请用Via浏览器或者Chrome浏览器预览。…

Vue的学习之旅-part4

Vue的学习之旅-part1 vue的自带指令v-if v-else-if v-else虚拟DOM的复用v-show 与 v-if 的不同之处&#xff1a;v-if v-show各自合适的使用位置&#xff1a; v-for 循环v-for 循环遍历 :key"item" 绑定key&#xff0c;区分循环的内容循环的应用&#xff1a; 前几篇博…

目标检测——色素性皮肤病数据集

一、重要性及意义 首先&#xff0c;色素性皮肤病变是一类常见的皮肤疾病&#xff0c;其发病率有逐年增高的趋势。这些病变可能由遗传或环境因素导致黑素细胞生成异常&#xff0c;如黑色素瘤等。黑色素瘤具有极高的恶性率和致死率&#xff0c;而且恶化可能性大&#xff0c;容易…

汇编——SSE打包整数

SSE也可以进行整数向量的加法&#xff0c;示例如下&#xff1a; ;sse_integer.asm extern printfsection .datadummy db 13 align 16pdivector1 dd 1dd 2dd 3dd 4pdivector2 dd 5dd 6dd 7dd 8fmt1 db "Packed Integer Vector 1: %d, %d, %d, %d",…

鸿蒙ArkTS开始实例:【canvas实现签名板功能】

使用ArkTS中的canvas实现签名板的功能&#xff0c;canvas画布大家都很熟悉&#xff0c;我们会用它经常实现一些画板或者图表、表格之类的功能。canvas签名板是我在开发APP过程中实现的一个功能&#xff0c;开发过程中也是遇到比较多的问题。我会按照以下几点来讲解开发整个过程…

面试算法-153-旋转图像

题目 给定一个 n n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。 你必须在 原地 旋转图像&#xff0c;这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,2,3],[4,5,6],[7,8,…

计算机网络实验——学习记录四(TCP协议)

1. 打开TCP服务&#xff1a; nc -e /bin/sh -lv 4499 注释&#xff1a; &#xff08;1&#xff09;nc是Linux下启动通讯服务的命令&#xff1b; &#xff08;2&#xff09;-e表示在nc命令后再执行bin文件夹下的shell命令&#xff0c;启动shell命令会导致所有从TCP连接传递到…

JavaEE初阶——多线程(一)

T04BF &#x1f44b;专栏: 算法|JAVA|MySQL|C语言 &#x1faf5; 小比特 大梦想 此篇文章与大家分享多线程的第一部分:引入线程以及创建多线程的几种方式 此文章是建立在前一篇文章进程的基础上的 如果有不足的或者错误的请您指出! 1.认识线程 我们知道现代的cpu大多都是多核心…