C语言数组详解-程序员宅基地

技术标签: 经验分享  C语言术语和结构总结  笔记  c语言  课程设计  开发语言  

系列文章目录

第一章 C语言基础知识

第二章 C语言控制语句

第三章 C语言函数详解

第四章 C语言数组详解

第五章 C语言操作符详解

第六章 C语言指针详解


文章目录

系列文章目录

文章目录

1. 一维数组

1.1 数组的创建

1.2 数组的初始化

1.3 一维数组的使用

2. 二维数组

2.1 二维数组的创建

2.2 二维数组的初始化

2.3 二维数组的使用

3. 数组作为函数参数

项目练习


1. 一维数组

数组是编程中一种基础且重要的数据结构,用于存储一系列相同类型的元素,这些元素在内存中是连续存放的。在 C 语言中,数组可以存储任何数据类型的元素,如整数、浮点数、字符等。了解数组的工作原理及其特性对于编写有效和高效的程序至关重要。

1.1 数组的创建

type arrayName[arraySize];
  •  type 是数组中元素的数据类型,如 intfloatchar 等。
  • arrayName 是你为数组选择的名称。
  • arraySize 是数组中元素的数量,必须是大于零的整数。
  • 数组在内存中是连续存放的。随着数组下标的增长,元素的地址,也在有规律的递增。  
int arr1[10];
char arr3[10];
float arr4[1];
double arr5[20];

1.2 数组的初始化

数组可以在声明时立即初始化,也可以在声明后通过索引进行初始化。

在声明时初始化

int numbers[5] = {1, 2, 3, 4, 5};
int numbers[5] = {1, 2}; // 等同于 {1, 2, 0, 0, 0}
int numbers[] = {1, 2, 3, 4, 5}; // 数组大小自动设为 5

使用索引初始化

int numbers[5];
numbers[0] = 1;
numbers[1] = 2;
numbers[2] = 3;
numbers[3] = 4;
numbers[4] = 5;

1.3 一维数组的使用

一旦数组被初始化,你可以通过索引访问任何位置的元素,进行读取或修改操作。

printf("%d\n", numbers[2]); // 输出 3
numbers[2] = 100; // 将数组中第三个元素修改为 100
printf("%d\n", numbers[2]); // 输出 100

2. 二维数组

2.1 二维数组的创建

二维数组在内存中也是连续存储的。

type arrayName[rows][columns];
  • type 是数组元素的数据类型,例如 intfloatchar
  • arrayName 是数组的名称。
  • rows 指定数组的行数。
  • columns 指定数组的列数。
int arr[3][4];
char arr[3][5];
double arr[2][4];

2.2 二维数组的初始化

在声明时初始化

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

如果省略某些值,它们会自动初始化为 0(对于基本数据类型):

int matrix[3][4] = {
  {1, 2},
  {5, 6},
  {9, 10}
};  // 缺失的元素将被初始化为 0

2.3 二维数组的使用

二维数组中的元素通过两个索引访问,一个用于行,一个用于列。

printf("%d\n", matrix[0][2]);  // 输出第一行第三列的元素,即 3
matrix[0][2] = 100;            // 修改第一行第三列的元素为 100

代码示例:

#include <stdio.h>
int main()
{
    // 声明并初始化一个 3 行 4 列的二维数组,所有元素初始化为 0
    int arr[3][4] = {0};
    
    // 外层循环,控制行的索引
    for(int i = 0; i < 3; i++)
    {
        // 内层循环,控制列的索引
        for(int j = 0; j < 4; j++)
        {
            // 为数组每个元素赋值,值为行索引乘以 4 加上列索引
            arr[i][j] = i * 4 + j;
        }
    }

    // 再次使用外层循环遍历数组行
    for(int i = 0; i < 3; i++)
    {
        // 内层循环遍历数组列
        for(int j = 0; j < 4; j++)
        {
            // 打印每个元素的值,后跟一个空格
            printf("%d ", arr[i][j]);
        }
        // 每打印完一行后输出换行符,以便每行打印在新的一行
        printf("\n");
    }

    return 0;
}

在这个嵌套循环中:

  • 外层循环变量 i 从 0 到 2,代表数组的行。
  • 内层循环变量 j 从 0 到 3,代表数组的列。

数组的每个元素 arr[i][j] 被赋值为 i*4+j。这种赋值方式使得数组的元素按照其在数组中的位置线性递增:

  • i = 0 时,各列的元素为 0, 1, 2, 3
  • i = 1 时,各列的元素为 4, 5, 6, 7
  • i = 2 时,各列的元素为 8, 9, 10, 11

3. 数组作为函数参数

在 C 语言中,数组可以作为参数传递给函数。这使得函数能够处理数组中的数据,执行诸如搜索、排序、统计等操作。然而,由于 C 语言的数组不存储其自身的长度信息,当数组作为参数传递给函数时,通常需要额外传递数组的长度。

传递方式

在 C 中,数组默认通过指针传递。当你将一个数组作为参数传递给函数时,实际上传递的是数组第一个元素的地址。这意味着在函数内部对数组元素所做的修改将影响原始数组。

函数声明

当你想在函数中使用数组时,可以在函数声明中使用以下任一方式声明数组参数:

void processArray(int arr[], int size);
void processArray(int *arr, int size);

这两种声明方式在功能上是等价的,arr[]*arr 都表示一个指向整数的指针,它指向数组(或其一部分)的起始位置。

在 C 语言中,数组名是指向数组第一个元素的指针。它代表数组在内存中的起始地址,因此通常被视为数组的首地址。数组名在不同的上下文中可以有稍微不同的行为,特别是在作为函数参数时,它们的行为就如同指向数组类型的指针。

例如,如果 arr 是一个整型数组,那么 arr 就可以被视为指向 arr[0] 的指针。尽管数组名本身表示数组的起始地址,但通过与索引配合使用,它可以访问数组中的任何元素。例如,arr[i] 访问从起始地址开始的第 i 个元素。

代码示例:
使用数组作为参数的函数示例,该函数计算整数数组的总和:

#include <stdio.h>

// 函数定义,计算整数数组的总和
int sumArray(int arr[], int size) {
    int sum = 0;  // 初始化总和为 0
    for (int i = 0; i < size; i++) {
        sum += arr[i];  // 将每个数组元素加到总和中
    }
    return sum;  // 返回计算的总和
}

int main() {
    int numbers[] = {1, 2, 3, 4, 5};  // 声明并初始化一个整数数组
    int total = sumArray(numbers, 5);  // 调用函数并传递数组和数组的大小
    printf("The total sum is: %d\n", total);
    return 0;
}

在这个示例中,sumArray 函数接收一个整数数组和数组的大小作为参数。函数内部使用 for 循环遍历数组,并将所有元素的值累加到 sum 变量中。由于数组是通过指针传递的,arr 参数在函数中直接引用了原始数组 numbers

项目练习

基于C语言的闯关游戏
(还没编完。。。正在努力中。。。)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/TENET123/article/details/137755945

智能推荐

使用IPSET屏蔽美国IP_ipset封禁国外ip-程序员宅基地

文章浏览阅读387次,点赞6次,收藏8次。最近被美国IP盯上了,瞄的不间断攻击ADD-TO-CART页面。记录下用IPSET屏蔽过程。执行如下脚本,将IP地址段中的记录转换为Ipset指令,保存在。_ipset封禁国外ip

nodejs的字符串操作模块_nodejs 字符串操作模块-程序员宅基地

文章浏览阅读3.2w次。nodejs字符串操作简介需要引入querystring对象,querystring对象的方法有stringifyquerystring.stringify(“对象”,“分隔符”,“分配符”),将一个json对象,转为字符串,通过指定的分隔符,以及分配符 具体代码:var querystring = require('querystring');var result = querystring.s_nodejs 字符串操作模块

李宏毅机器学习笔记第1周-机器学习基本概念_anomaly compression-程序员宅基地

文章浏览阅读855次。机器学习基本概念_anomaly compression

MD5碰撞-程序员宅基地

文章浏览阅读9.4k次,点赞29次,收藏109次。在CTF中可以说是经常碰到md5加密了,一般都是进行强比较抑或是弱比较,考法非常多,但是万变不离其中。只要我们掌握了原理,一切问题便迎刃而解了。文章首发于我的博客,格式可能比较清晰,有兴趣了解CTF中MD5碰撞的伙伴可以移步查看。_md5碰撞

普里姆算法c语言(详细解读)_c语言普里姆算法-程序员宅基地

文章浏览阅读854次,点赞5次,收藏12次。找到与这个系统邻接的边(0,1),(5,4),比较两者的权值,容易发现权值最小的为25,因此加入边(5,4),同时加入结点4和边(5,4)。4.将0,5,4,3以及相关的边看成一个整体,与其邻接的边有(0,1)28,(4,6)24,(3,6)18,(3,2)12,四个边中权值最小的边是(3,2),所以加入结点2以及边(3,2)。5.与4中所构成的整体邻接的边有(0,1)28,(4,6)24,(3,6)18,(2,1)16,四者中权值最小的边为(2,1),所以加入结点1以及边(2,1)。_c语言普里姆算法

nohub 和 & 在linux上不间断后台运行程序-程序员宅基地

文章浏览阅读3.1k次,点赞2次,收藏15次。长时间在服务器上运行深度学习代码,使用nohub 命令行 & 可以让代码不间断在后台运行_nohub

随便推点

docker配置国内镜像源_docker国内镜像源-程序员宅基地

文章浏览阅读3.3w次,点赞9次,收藏25次。刚开始学习docker,发现下载镜像非常的慢。如果不经过,docker的镜像下载都来源于国外,因此需要配置国内的镜像源。Docker中国区官方镜像。_docker国内镜像源

Unity中怎么播放视频_unity 播放视频-程序员宅基地

文章浏览阅读1.9w次,点赞40次,收藏209次。一.首先在场景中新建UI中的Raw Image可以按住Alt再点击下图红色箭头所示将Raw Image铺满游戏全屏(也可以自己调整大小)二.给Raw Image添加Video Player组件三.在Assets或者自己想要的文件夹中创建Render Texture四.将准备好的视频(这里用到的视频格式是mp4)拖入项目中并做如下修改这里我把新建的Render Texture命名为2,拖入的视频也命名为2(随便命的,不要在意)这里我们看到这个Render Te..._unity 播放视频

使用BOOTICE 恢复系统启动项_bootice保存后没用-程序员宅基地

文章浏览阅读9.7k次,点赞2次,收藏9次。使用BOOTICE 恢复系统启动项我在安装deepin 系统的时候,经常遇到重启进不去系统,每次重启都会进入windows 系统,这让我感到特别头疼,试了好多次都不成功,有些情况是,成功后再次重启又回到了windows系统。后来终于在PE中利用一款叫做BOOT ICE的工具成功解决。BOOTICE— 引导扇区维护工具简介BOOTICE 是一个启动相关的维护的小工具,主要用于安装、修复、备份和恢复磁盘_bootice保存后没用

文本分类与SVM_svm分类-程序员宅基地

文章浏览阅读9.5w次,点赞54次,收藏202次。之前做过一些文本挖掘的项目,比如网页分类、微博情感分析、用户评论挖掘,也曾经将libsvm进行包装,写了一个文本分类的开软软件Tmsvm。所以这里将之前做过一些关于文本分类的东西整理总结一下。1 基础知识1. 1 样本整理文本分类属于有监督的学习,所以需要整理样本。根据业务需求,确定样本标签与数目,其中样本标签多为整数。在svm中其中如果为二分类,样本标签一般会设定为-1和_svm分类

力扣——206.反转链表_力扣链表反转-程序员宅基地

文章浏览阅读141次。题目python代码方法一:利用新列表,创建新的链表# Definition for singly-linked list.# class ListNode(object):# def __init__(self, val=0, next=None):# self.val = val# self.next = nextclass Solution(object): def reverseList(self, head): ""_力扣链表反转

如何解决深度冲突(Z-fighting),画面闪烁的问题-程序员宅基地

文章浏览阅读3.6k次,点赞3次,收藏6次。参考:OpenGL教程:深度测试深度冲突一个很常见的视觉错误会在两个平面或者三角形非常紧密地平行排列在一起时会发生,深度缓冲没有足够的精度来决定两个形状哪个在前面。结果就是这两个形状不断地在切换前后顺序,这会导致很奇怪的花纹。这个现象叫做深度冲突(Z-fighting),因为它看起来像是这两个形状在争夺(Fight)谁该处于顶端。防止深度冲突第一个也是最重要的技巧是永远不要把多个物体摆得太靠近,以至于它们的一些三角形会重叠。通过在两个物体之间设置一个用户无法注意到的偏移值,你可以完全避免这两个物体之_深度冲突

推荐文章

热门文章

相关标签