当前位置: 首页 > article >正文

C语言数组知识点

一、数组的基本概念

     1.定义

数组是相同数据类型元素的集合,通过连续内存存储,支持高效访问。

核心特点

  • 元素类型相同

  • 内存连续分配

  • 通过下标访问(从 0 开始)

      2.分类

  • 一维数组:线性结构(如 int arr[5]
  • 多维数组:嵌套结构(如二维数组 int arr[3][4]


二、一维数组

     1.声明与初始化

     声明格式数据类型 数组名[元素个数];

int arr[5];          // 声明未初始化(局部变量元素值为随机数)  
static int s_arr[3]; // 静态数组未初始化元素默认为0  
  • 初始化方式

    初始化类型示例代码说明
    完全初始化int arr[3] = {1, 2, 3};所有元素显式赋值
    部分初始化int arr[5] = {1, 2};剩余元素自动补0(仅全局/静态数组有效)
    长度自动推断int arr[] = {10, 20, 30};等价于 arr[3]
    2.内存特性

           连续存储:相邻元素地址差为 sizeof(元素类型)

int arr[3] = {1, 2, 3};  
printf("地址差:%td\n", (char*)&arr[1] - (char*)&arr[0]); // 输出:4(假设int占4字节)  
  • 越界风险:C语言不检查数组边界,越界访问可能导致程序崩溃或数据污染。

    int arr[3] = {1};  
    arr[3] = 100; // 危险操作!覆盖未知内存区域  

    3.数组名与指针关系

      数组名本质:数组名在大多数场景下退化为指向首元素的指针

int arr[5] = {0};  
int *p = arr;          // 合法,p指向arr[0]  
int (*p_arr)[5] = &arr; // 数组指针类型  

例外情况

  • sizeof(arr):返回整个数组的字节大小(如 int[5] 返回 20

  • &arr:返回指向整个数组的指针(类型为 int(*)[5]


三、二维数组
  1. 声明与初始化

        声明格式数据类型 数组名[行数][列数];

int matrix[3][4]; // 3行4列的二维数组  
  • 初始化方式

    初始化类型示例代码说明
    完全初始化(分行)int m[2][3] = {{1,2,3}, {4,5,6}};每行显式赋值
    连续初始化int m[2][3] = {1,2,3,4,5,6};按行优先顺序填充
    部分初始化int m[3][4] = {{1}, {0,5}, [2]={9,8}};C99支持指定行初始化
    2.内存布局

行优先存储:二维数组本质是一维数组的嵌套,内存按行连续分配。

int arr[2][3] = {{1,2,3}, {4,5,6}};  
// 内存地址验证  
printf("行间地址差:%td\n", (char*)&arr[1][0] - (char*)&arr[0][0]); // 输出:12(假设int为4字节)  

多维数组的指针视角

二维数组名退化为指向第一行(子数组)的指针:

int arr[2][3];  
int (*p_row)[3] = arr; // p_row指向第一行(类型为int(*)[3]) 

四、动态数组

1.动态内存分配

使用 malloccallocrealloc 和 free 实现动态数组:

// 动态创建数组  
int *dyn_arr = (int*)malloc(10 * sizeof(int));  
if (dyn_arr == NULL) {  perror("内存分配失败");  exit(EXIT_FAILURE);  
}  // 扩容数组(从10元素扩展到20)  
int *temp = (int*)realloc(dyn_arr, 20 * sizeof(int));  
if (temp != NULL) {  dyn_arr = temp;  
} else {  free(dyn_arr); // 扩容失败需释放原内存  
}  // 释放内存  
free(dyn_arr);  

2.变长数组(VLA)

  • C99标准支持:数组长度在运行时确定(部分编译器可能不支持)。

    
    void func(int n) {  int vla[n]; // 变长数组  // ...  
    } // 生命周期结束后自动释放  


五、数组的常见用法

1.遍历数组

  • 一维数组遍历:

    int arr[5] = {1,2,3,4,5};  
    for (int i=0; i<sizeof(arr)/sizeof(arr[0]); i++) {  printf("%d ", arr[i]);  
    }  

  • 二维数组遍历:

    int matrix[3][4] = {0};  
    for (int i=0; i<3; i++) {  for (int j=0; j<4; j++) {  matrix[i][j] = i + j;  }  
    }  

2.数组作为函数参数

  • 传递方式:数组名退化为指针,需额外传递长度信息。

    // 一维数组作为参数  
    void printArray(int arr[], int len) { // 等价于int *arr  for (int i=0; i<len; i++) {  printf("%d ", arr[i]);  }  
    }  // 二维数组作为参数(需指定列数)  
    void printMatrix(int mat[][4], int rows) {  for (int i=0; i<rows; i++) {  for (int j=0; j<4; j++) {  printf("%d ", mat[i][j]);  }  }  
    }  


六、注意事项与常见错误

1.常见错误

  • 越界访问:导致未定义行为(崩溃或数据损坏)

    
    int arr[3] = {1,2,3};  
    arr[3] = 4; // 错误!越界访问  

  • 未初始化的局部数组:元素值为随机数

    int arr[5];  
    printf("%d", arr[0]); // 输出不确定的值  

2.数组与指针的陷阱

  • 数组名不可修改

    int arr[5] = {0};  
    arr++; // 错误!数组名不是左值  

  • 指针与数组长度计算

    int arr[5];  
    int *p = arr;  
    printf("数组长度错误计算:%zu\n", sizeof(p)/sizeof(int)); // 输出:1或2(指针大小)  


七、代码示例:数组综合应用

#include <stdio.h>  
#include <stdlib.h>  // 动态创建并操作二维数组  
void dynamicMatrixDemo() {  int rows = 3, cols = 4;  // 动态分配内存  int **matrix = (int**)malloc(rows * sizeof(int*));  for (int i=0; i<rows; i++) {  matrix[i] = (int*)malloc(cols * sizeof(int));  }  // 赋值与打印  for (int i=0; i<rows; i++) {  for (int j=0; j<cols; j++) {  matrix[i][j] = i * cols + j;  printf("%2d ", matrix[i][j]);  }  printf("\n");  }  // 释放内存  for (int i=0; i<rows; i++) {  free(matrix[i]);  }  free(matrix);  
}  int main() {  dynamicMatrixDemo();  return 0;  
}  

总结

核心原则:数组是C语言中连续内存块的直接体现,需手动管理内存与边界。

关键区别

  • 静态数组(编译时确定大小) vs 动态数组(运行时分配)

  • 一维数组(线性访问) vs 多维数组(嵌套结构)

安全实践

  • 始终检查数组边界

  • 动态内存分配后验证指针有效性

  • 使用 sizeof(arr)/sizeof(arr[0]) 计算静态数组长度

通过掌握数组的内存布局、指针关系及动态管理,可高效处理批量数据,同时避免常见陷阱。

相关文章:

C语言数组知识点

一、数组的基本概念 1.定义 数组是相同数据类型元素的集合&#xff0c;通过连续内存存储&#xff0c;支持高效访问。 核心特点&#xff1a; 元素类型相同 内存连续分配 通过下标访问&#xff08;从 0 开始&#xff09; 2.分类 一维数组&#xff1a;线性结构&#xff08;如…...

【新手初学】SQL注入getshell

一、引入 木马介绍&#xff1a; 木马其实就是一段程序&#xff0c;这个程序运行到目标主机上时&#xff0c;主要可以对目标进行远程控制、盗取信息等功能&#xff0c;一般不会破坏目标主机&#xff0c;当然&#xff0c;这也看黑客是否想要搞破坏。 木马类型&#xff1a; 按照功…...

DAY 34 leetcode 349--哈希表.两个数组的交集

题号349 我尝试硬解失败 /*class Solution {public int[] intersection(int[] nums1, int[] nums2) {int n1nums1.length;int n2nums2.length;int sizeMath.min(n1,n2);int []arrnew int[size];int count0;for(int i0;i<n1;i){outerloop:for(int j0;j<n2;j){if(nums1[i…...

Qt常用宏定义判断大全

Qt 提供了一系列预定义宏用于判断 Qt 版本、操作系统平台、编译器特性等。这些宏在跨平台开发中非常有用。 1. Qt 版本判断宏 // 检查Qt版本 #if QT_VERSION > QT_VERSION_CHECK(5, 15, 0)// Qt 5.15.0及以上版本特有代码 #endif// 常用版本判断 #if QT_VERSION > QT_V…...

tsconfig.json:error TS6306: Referenced project ‘/tsconfig.node.json‘

这是TypeScript配置文件中的错误。具体有两个问题&#xff1a; 错误TS6306&#xff1a;引用的项目/tsconfig.node.json必须设置"composite": true错误TS6310&#xff1a;引用的项目tsconfig.node.json不能禁用emit 要解决这些问题&#xff0c;需要修改tsconfig.nod…...

14-SpringBoot3入门-MyBatis-Plus之CRUD

1、整合 13-SpringBoot3入门-整合MyBatis-Plus-CSDN博客 2、表 3、crud package com.sgu;import com.sgu.mapper.UserMapper; import com.sgu.pojo.User; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.spri…...

前端面试常考算法题目详解

根据2025年最新前端面试趋势&#xff0c;结合腾讯、阿里等大厂真题&#xff0c;我为你整理了以下高频算法题型及JS实现方案&#xff1a; 一、数组/字符串处理 1. 两数之和&#xff08;哈希表法&#xff09; 问题&#xff1a;找出数组中两数之和等于目标值的索引 const twoSu…...

三轴云台之相机技术篇

一、结构设计 三轴云台通常由空间上三个互相垂直的框架构成&#xff0c;包括内框&#xff08;俯仰框&#xff09;、中框&#xff08;方位框&#xff09;和外框&#xff08;横滚框&#xff09;。这些框架分别负责控制相机的俯仰运动、方位运动和横滚运动&#xff0c;从而实现对目…...

质量和工艺之间的区别与联系?

我们生活中常常会遇到这些现象:冰箱漏水,修手机,电脑死机卡死,空调不制冷等等一些现象,我相信99%用户的第一反应是产品的质量不太行对吧! 其实不然,站在专业分析角度,难道冰箱漏水就一定是质量的问题吗? 不一定,小编认为要根本原因出发考虑,冰箱漏水了,可能和工艺…...

Bugku-再也没有纯白的灵魂

下载文件发现是兽音先用https://roar.iiilab.com/加密flag 得到“~呜嗷嗷嗷嗷呜啊嗷啊呜呜嗷呜呜~嗷嗷~啊嗷啊呜嗷嗷~嗷~嗷~呜呜嗷呜啊啊”&#xff0c;与密文对比对比发现字段少个啊&#xff0c;并且B对应嗷&#xff0c;U对应呜&#xff0c;G对应啊&#xff0c;K对应~补充啊后…...

推导Bias² + Variance + σ²_ε

问题的背景 我们有一个真实函数 f ( x ) f(x) f(x) 和基于训练数据 D D D 训练得到的模型 f ^ ( x ; D ) \hat{f}(x;D) f^​(x;D)。对于任意输入 x x x&#xff1a; y y y 是真实的观测值&#xff0c;定义为 y f ( x ) ϵ y f(x) \epsilon yf(x)ϵ&#xff0c;其中 …...

多模态大语言模型arxiv论文略读(一)

Does Transliteration Help Multilingual Language Modeling? ➡️ 论文标题&#xff1a;Does Transliteration Help Multilingual Language Modeling? ➡️ 论文作者&#xff1a;Ibraheem Muhammad Moosa, Mahmud Elahi Akhter, Ashfia Binte Habib ➡️ 研究机构: Pennsyl…...

单元测试原则之——不要模拟不属于你的类型

在单元测试中,不要模拟不属于你的类型(Don’t mock types you don’t own)是一个重要的原则。这是因为外部库或框架的类型(如第三方依赖)可能会在未来的版本中发生变化,而你的模拟可能无法反映这些变化,从而导致测试失效。 以下是一个基于Java Mockito 的示例,展示如何…...

算法与数据结构面试题

算法与数据结构面试题 加油&#xff01; 考查数据结构本身 什么是数据结构 简单地说&#xff0c;数据结构是以某种特定的布局方式存储数据的容器。这种“布局方式”决定了数据结构对于某些操作是高效的&#xff0c;而对于其他操作则是低效的。首先我们需要理解各种数据结构&a…...

边缘检测技术现状初探2:多尺度与形态学方法

一、多尺度边缘检测方法 多尺度边缘检测通过在不同分辨率/平滑度下分析图像&#xff0c;实现&#xff1a; 粗尺度&#xff08;大σ值&#xff09;&#xff1a;抑制噪声&#xff0c;提取主体轮廓细尺度&#xff08;小σ值&#xff09;&#xff1a;保留细节&#xff0c;检测微观…...

【AI News | 20250402】每日AI进展

AI Repos 1、Dolphin 由数据海洋AI与清华大学联合研发的Dolphin多任务语音识别模型正式亮相。该模型覆盖东亚、南亚、东南亚及中东地区40余种语言&#xff0c;并支持22种汉语方言&#xff0c;训练数据量超21万小时&#xff08;含自有及开源数据&#xff09;&#xff0c;具备语…...

大智慧前端面试题及参考答案

如何实现水平垂直居中? 在前端开发中,实现元素的水平垂直居中是一个常见的需求,以下是几种常见的实现方式: 使用绝对定位和负边距:将元素的position设置为absolute,然后通过top、left属性将其定位到父元素的中心位置,再使用负的margin值来调整元素自身的偏移,使其水平垂…...

LLM 分词器Tokenizer 如何从 0 到 1 训练出来

写在前面 大型语言模型(LLM)处理的是人类的自然语言,但计算机本质上只能理解数字。Tokenizer(分词器) 就是架在自然语言和计算机数字表示之间的一座至关重要的桥梁。它负责将我们输入的文本字符串分解成模型能够理解的最小单元——Token,并将这些 Token 转换成对应的数字…...

操作系统高频(七)虚拟地址与页表

操作系统高频&#xff08;六&#xff09;虚拟地址与页表 1.什么是文件系统&#xff1f;它的作用是什么&#xff1f;⭐ 存储管理&#xff1a;文件系统负责管理计算机的存储设备&#xff0c;如硬盘、固态硬盘等。它将文件存储在这些设备上&#xff0c;并负责分配和回收存储空间…...

openEuler24.03 LTS下安装Flume

目录 前提条件 下载Flume 解压 设置环境变量 修改日志文件 测试Flume 在node2安装Flume 前提条件 Linux安装好jdk Flume一般需要配合Hadoop使用&#xff0c;安装好Hadoop完全分布式集群&#xff0c;可参考&#xff1a;openEuler24.03 LTS下安装Hadoop3完全分布式 下载F…...

现代几何风格网页标牌标识logo海报标题设计psai英文字体安装包 Myfonts – Gilroy Font Family

Gilroy 是一款具有几何风格的现代无衬线字体。它是原始 Qanelas 字体系列的弟弟。它有 20 种粗细、10 种直立字体和与之匹配的斜体。Light 和 ExtraBold 粗细是免费的&#xff0c;因此您可以随心所欲地使用它们。设计时考虑到了强大的 opentype 功能。每种粗细都包括扩展语言支…...

ControlNet-Tile详解

一、模型功能与应用 1. 模型功能 ControlNet-Tile模型的主要功能是图像的细节增强和质量提升。它通过以下几个步骤实现这一目标&#xff1a; 语义分割&#xff1a;模型首先对输入的图像进行语义分割&#xff0c;识别出图像中不同的区域和对象。这一步是为了让模型理解图像的内…...

leetcode 2873. 有序三元组中的最大值 I

欢迎关注更多精彩 关注我&#xff0c;学习常用算法与数据结构&#xff0c;一题多解&#xff0c;降维打击。 文章目录 题目描述题目剖析&信息挖掘解题思路方法一 暴力枚举法思路注意复杂度代码实现 方法二 公式拆分动态规划思路注意复杂度代码实现 题目描述 [2873] 有序三元…...

Java创建对象和spring创建对象的过程和区别

暮乘白帝过重山 从new到IoC的演进&#xff0c;体现了软件工程从"怎么做"到"做什么"的思维转变。理解Java对象创建的底层机制&#xff0c;是写出高性能代码的基础&#xff1b;掌握Spring的Bean管理哲学&#xff0c;则是构建可维护大型系统的关键。二者如同…...

RabbitMQ应用2

RabbitMQ应用2 一.实际业务逻辑订单系统中使用MQ&#xff08;不写订单系统逻辑&#xff09;1.项目的创建和准备2.代码实现ControllerConfigurationproperties 二.物流系统使用MQ&#xff08;不实现物流系统业务&#xff09;1.项目创建同订单&#xff08;一样&#xff09;2.代码…...

Windows 实战-evtx 文件分析--笔记

Windows 取证之EVTX日志 - 蚁景网安实验室 - 博客园 一.evtx日志文件是什么 从 Windows NT 6.0&#xff08;也就是 Windows Vista 和 Windows Server 2008&#xff09;开始&#xff0c;微软引入了一种全新的日志文件格式&#xff0c;称为 evtx。这种格式取代了之前 Windows 系…...

Vue3的组件通信

父子通信 父传子 1.父组件给子组件添加属性传值 const myCount ref(10) ... <son :count"myCount"/>2.子组件通过defineProps编译器宏接收 const props defineProps({count: Number })3.子组件使用 {{count}}子传父 1. 父组件实现处理函数 const getM…...

【postgresql】锁概览

常规锁 场景测试案例...

python中的 f 是什么意思,f‘{username}_log_archive_{int(time.time())}.txt‘

python中的 f 是什么意思,f’{username}log_archive{int(time.time())}.txt’ 在 Python 中,f 是一种字符串前缀,用于创建格式化字符串(也称为 f-string),它是 Python 3.6 及更高版本引入的一种方便的字符串格式化方式。 基本语法和功能 当你在字符串前加上 f 前缀时,…...

子组件使用:visible.sync=“visible“进行双向的绑定导致该弹窗与其他弹窗同时显示的问题

问题描述&#xff1a;最近写代码时遇到了一个问题&#xff1a;点击A弹窗后关闭&#xff0c;继续点击B弹窗&#xff0c;这时会同时弹窗A、B两个弹窗。经过排查后发现在子组件定义时使用了:visible.sync"visible"属性进行双向的数据绑定 <template> <el-dial…...