【C语言】基础语法5:数组和指针

news/2024/4/26 4:35:33/文章来源:https://blog.csdn.net/PoGeN1/article/details/130306647

上一篇:函数和递归
下一篇:字符串和字符处理

❤️‍🔥前情提要❤️‍🔥
  欢迎来到C语言基本语法教程
  在本专栏结束后会将所有内容整理成思维导图(结束换链接)并免费提供给大家学习,希望大家纠错指正。本专栏将以基础出发,在之后的教程中将会不断学习并详细讲解C语言的基本语法及其高级用法
  上一节讲了C语言基础中的函数和递归,接下来让我们来一起学习C语言中的数组和指针
请添加图片描述
  🍪本教程内容干货满满,跟上步伐吧~🍪


作者介绍

🎓 作者:某不知名编程爱好者📜
🗒️系列文章&专栏推荐: 🔗《华为机试题解析》 、🔗《C语言程序设计》、🔗 《MySQL数据库》
🕸️为大家推荐一款很好用的C语言刷题网站🔗点击跳转


🔖导航小助手🔖

  • 📑 数组和指针
  • 📑 1. 数组
    • 🏷️ 1.1 数组的定义
    • 🏷️ 1.2 数组的使用方法
    • 🏷️ 1.3 数组的初始化
    • 🏷️ 1.4 数组的遍历
    • 🏷️ 1.5 数组的常见问题
  • 📑 2. 指针
    • 🏷️ 2.1 指针的定义
    • 🏷️ 2.2 指针的使用方法
    • 🏷️ 2.3 指针的运算
    • 🏷️ 2.4 指针的关系操作
    • 🏷️ 2.5 指针地址的转换
    • 🏷️ 2.6 指针的应用场景
  • 📑 3. 数组指针
    • 🏷️ 3.1 数组指针的定义
    • 🏷️ 3.2 数组指针和指针数组
    • 🏷️ 3.3 数组指针的应用场景
  • 📑 4. 多维数组
    • 🏷️ 4.1 二维数组的定义
    • 🏷️ 4.2 二维数组的使用方法
    • 🏷️ 4.3 二维数组的初始化
    • 🏷️ 4.4 多维数组的定义和使用
  • 📑 5. 数组和指针在函数中的应用
    • 🏷️ 5.1 数组作为函数的参数
    • 🏷️ 5.2 指针作为函数的参数
    • 🏷️ 5.3 数组指针作为函数的参数
    • 🏷️ 5.4 函数返回指针
  • 📑 6. 数组和指针的高级应用
    • 🏷️ 6.1 动态内存分配
    • 🏷️ 6.2 指向函数的指针
    • 🏷️ 6.3 结构体和指针数组的结合使用
    • 🏷️ 6.4 指令和指针的安全使用
  • ⚠️ 注意事项
    • 🎀小结


📑 数组和指针

  • C语言中数组指针的使用是任何一个程序员必须掌握的基础知识。数组作为一种常用的数据结构,可以用于存储一系列同一类型的数据指针则是C语言中的重要概念之一,它指向一个内存地址,可以用于数据的传递和操作

📑 1. 数组


🏷️ 1.1 数组的定义

  • 在C语言中,数组可以定义为一组相同类型的数据元素的集合。数组中的每个元素都可以通过一个下标访问,下标从0开始计数。数组的定义方式如下:
数据类型 数组名[数组长度];

例如,定义一个长度为10的int类型数组:

int arr[10];

🏷️ 1.2 数组的使用方法

数组的元素可以通过下标来访问,例如:

arr[0] = 1;

上述语句将数组arr的第一个元素赋值为1。数组的元素也可以通过循环来遍历

for (int i = 0; i < 10; i++) {arr[i] = i;
}

上述语句将数组arr的元素依次赋值为0~9


🏷️ 1.3 数组的初始化

在定义数组时,可以直接初始化数组元素的值

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

上述语句定义了一个长度为5的int类型数组,并将其元素依次初始化为1~5。


🏷️ 1.4 数组的遍历

数组的遍历可以使用for循环来实现:

for (int i = 0; i < 5; i++) {printf("%d ", arr[i]);
}

上述语句将数组arr的所有元素按顺序输出。


🏷️ 1.5 数组的常见问题

数组的下标越界是C语言中常见的问题,使用数组时一定要确保下标不超出数组的范围。另外,数组在作为函数参数传递时会自动转换为指针,这也是需要注意的地方。


📑 2. 指针


🏷️ 2.1 指针的定义

指针是一个存储变量地址的变量。指针的定义方式如下:

数据类型 *指针变量名;

例如,定义一个int类型的指针变量:

int *ptr;

🏷️ 2.2 指针的使用方法

指针可以用于访问修改变量的值,例如:

int a = 10;
int *ptr = &a;
*ptr = 20;

上述语句将变量a的值修改为20。指针也可以通过循环来遍历数组

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

上述语句将数组arr的所有元素按顺序输出。


🏷️ 2.3 指针的运算

指针也可以进行加减运算,例如:

int arr[5] = {1, 2, 3, 4, 5};
int *ptr = arr;
printf("%d\n", *(ptr+3));   //输出4

指针也可以自增自减,例如:

int arr[5] = {1, 2, 3, 4, 5};
int *ptr = arr;
ptr++;  //指向arr[1]

🏷️ 2.4 指针的关系操作

指针也可以进行关系运算,例如:

int a = 10;
int b = 20;
int *pa = &a;
int *pb = &b;
if (pa < pb) {printf("pa < pb\n");
}
else {printf("pa >= pb\n");
}

上述语句将输出"pa < pb",因为指针pa指向的变量a在内存中的地址小于指针pb指向的变量b在内存中的地址。(运行结果可能会不同)


🏷️ 2.5 指针地址的转换

指针地址可以通过强制类型转换变为不同数据类型的指针,例如:

int a = 10;
float *ptr = (float *)&a;
*ptr = 10.5;
printf("%.2f\n", (float)a);

上述语句将输出"10.50",因为将整型变量a的地址强制转换为float型指针后,可以将其看作一个浮点数变量。(运行结果可能会不同)


🏷️ 2.6 指针的应用场景

指针可以用于数据结构动态内存分配等场景中,例如链表等数据结构;以及malloc()free()函数进行动态内存分配等。


📑 3. 数组指针


🏷️ 3.1 数组指针的定义

数组指针指向数组的指针。数组指针的定义方式如下:

数据类型 (*数组指针变量名)[数组长度];

例如,定义一个指向int类型数组的指针:

int arr[5];
int (*ptr)[5] = &arr;

🏷️ 3.2 数组指针和指针数组

数组指针指针数组是两个不同的概念。指针数组是一个数组,其中每个元素都是一个指针。而数组指针一个指向数组的指针

例如,定义一个指针数组和一个数组指针:

int a = 1, b = 2, c = 3;
int *arr[] = {&a, &b, &c};   //指针数组
int arr1[3] = {1, 2, 3};
int (*ptr)[3] = &arr1;   //数组指针

🏷️ 3.3 数组指针的应用场景

数组指针可以用于多维数组访问传递,例如:

int arr[2][3] = {{1, 2, 3}, {4, 5, 6}};
int (*ptr)[3] = arr;
for (int i = 0; i < 2; i++) {for (int j = 0; j < 3; j++) {printf("%d ", *(*(ptr+i)+j));}printf("\n");
}

上述语句将多维数组arr的所有元素按顺序输出。


📑 4. 多维数组


🏷️ 4.1 二维数组的定义

在C语言中,可以定义多维数组。二维数组是最常见的多维数组。定义一个二维数组的方式如下:

数据类型 数组名[行数][列数];

例如,定义一个3行4列的int类型二维数组:

int arr[3][4];

🏷️ 4.2 二维数组的使用方法

二维数组的元素可以通过索引访问,例如:

int arr[3][4];
arr[0][1] = 1;

上述语句将二维数组arr的第一行第二列的元素赋值为1。


🏷️ 4.3 二维数组的初始化

在定义二维数组时,可以直接初始化数组元素的值

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

上述语句定义了一个3行4列的int类型二维数组,并将其元素依次初始化为1~12。


🏷️ 4.4 多维数组的定义和使用

类似地,C语言中还可以定义三维及以上的多维数组,例如:

int arr[2][3][4];
arr[0][1][2] = 1;

上述语句定义了一个2x3x4的int类型的三维数组,并将其第一块的第二行第三列的元素赋值为1。


📑 5. 数组和指针在函数中的应用


🏷️ 5.1 数组作为函数的参数

在函数中,数组可以作为参数传递。定义一个接受数组作为参数的函数的方式如下:

void func(int arr[], int len);

其中,arr是一个int类型的数组,len是数组的长度。


🏷️ 5.2 指针作为函数的参数

指针也可以作为参数传递

void func(int *ptr, int len);

其中,ptr是一个int类型的指针,len是数组的长度。


🏷️ 5.3 数组指针作为函数的参数

数组指针也可以作为参数传递

void func(int (*ptr)[5], int len);

其中,ptr是一个指向int类型数组的指针,len是数组的长度。


🏷️ 5.4 函数返回指针

函数也可以返回指针,例如:

int *func();

上述函数定义了一个返回int类型指针的函数。


📑 6. 数组和指针的高级应用


🏷️ 6.1 动态内存分配

动态内存分配可以通过malloc()函数实现:

int *ptr = malloc(10 * sizeof(int));

上述语句定义了一个长度为10的int类型的动态数组。


🏷️ 6.2 指向函数的指针

指向函数的指针可以通过以下方式定义:

int (*func)();

上述语句定义了一个指向返回int类型的函数的指针。


🏷️ 6.3 结构体和指针数组的结合使用

结构体指针数组可以结合使用来表示复杂的数据结构,并通过指针来进行操作,例如:

struct student {char name[20];int age;
};
struct student stu_arr[3] = {{"Tom", 18}, {"Jack", 19}, {"Lucy", 20}};
struct student *ptr_arr[3];
for (int i = 0; i < 3; i++) {ptr_arr[i] = &stu_arr[i];
}
for (int i = 0; i < 3; i++) {printf("%s %d\n", ptr_arr[i]->name, ptr_arr[i]->age);
}

上述语句定义了一个结构体数组,然后将每个元素的地址保存到一个指针数组中,并对每个结构体进行操作。


🏷️ 6.4 指令和指针的安全使用

为了防止指针访问非法内存地址,通过检查指针的值或使用NULL来进行指针的安全使用,例如:

int *ptr = NULL;
if (ptr != NULL) {*ptr = 1;
}

上述语句判断指针ptr是否为NULL,如果不是,则进行赋值操作。


⚠️ 注意事项

  • 使用数组时,一定要确保下标不超出数组的范围,否则会出现程序崩溃、数据错误等问题。

  • 使用指针时,一定要确保指针不是空指针,否则会出现程序崩溃的问题,可以使用空指针常量NULL进行判断。

  • 定义指针变量时,一定要对其进行初始化,否则可能指向非法地址,导致程序崩溃。

  • 指针使用完成后,应该及时将其置空,避免误用导致程序出现问题。

  • 数组在作为函数参数传递时会自动转换为指针,此时需要注意指针和数组的区别。

  • 使用malloc()等动态内存分配函数时,一定要释放已分配的内存,避免内存泄漏。

  • 指针类型转换时需要注意数据类型的匹配,否则会出现数据错误。

  • 处理多级指针时,需要注意指针的级别,如二级指针需要使用二级指针变量来存储和传递指针的地址。

对于数组指针的使用,需要掌握基本的概念和语法,同时需要注意数据类型的匹配数据访问的安全性,避免程序出现错误和安全问题。


上一篇:函数和递归
下一篇:字符串和字符处理


🎀小结

本文介绍了C语言中数组和指针的基本概念和用法,并讲解了数组指针多维数组的使用。同时,本文还介绍了数组和指针在函数中的应用,以及动态内存分配指向函数的指针结构体指针数组的结合使用等高级应用。通过本文的学习,读者可以更好地掌握C语言中数组和指针的使用,为后续的程序开发打下基础。

🔚以上就是C语言数组和指针的全部知识了~

🤗感谢大家的阅读~

📬后续还会继续更新💓,欢迎持续关注哟~📌

💫如果有错误❌,欢迎指正呀💫

✨如果觉得收获满满,可以点点赞👍支持一下哟~✨


在这里插入图片描述


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

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

相关文章

记一次死锁问题

最近在做一个需求&#xff0c;碰到了死锁的问题&#xff0c;记录下解决问题的过程 背景 这个需求要改动一个接口&#xff0c;我这边称为A接口&#xff0c;原先的逻辑是A接口内部会调用c方法&#xff0c;c方法是一个dubbo方法&#xff0c; 现在需要再A接口里添加调用B方法&…

【ROS】ubuntu18.04安装ROS(ROS1 Melodic)

1、添加中科大ROS源 1.1、添加源 sudo sh -c . /etc/lsb-release && echo "deb http://mirrors.ustc.edu.cn/ros/ubuntu/ lsb_release -cs main" > /etc/apt/sources.list.d/ros-latest.list1. 2、添加公钥 sudo apt-key adv --keyserver hkp://keyser…

编译预处理

编译预处理 1、宏定义1.1、 无参宏定义1.2、使用宏定义的优点1.3、宏定义注意点1.4、带参数的宏(重点)1.5、条件编译1.6、宏定义的一些巧妙用法(有用)1.7、结构体占用字节数的计算原则&#xff08;考题经常考&#xff0c;要会画图&#xff09;1.8、#在宏定义中的作用&#xff0…

ESP32设备驱动-BMM150数字地磁传感器驱动

BMM150数字地磁传感器驱动 文章目录 BMM150数字地磁传感器驱动1、BMM150介绍2、硬件准备3、软件准备4、驱动实现1、BMM150介绍 BMM150 是一款低功耗、低噪声的 3 轴数字地磁传感器,用于罗盘应用。 具有 1.56 x 1.56 mm 和 0.60 mm 高度的 12 引脚晶圆级芯片级封装 (WLCSP) 为…

直升机空气动力学基础--004翼型的阻力

来源 1. 空气的粘性 2.阻力的产生 3.形成因素 4.阻力系数曲线

转换json格式的日期为Javascript对象的函数

项目中碰到了用jQuery从后台获取的json格式的日期的字符串&#xff0c;需要将此字符串转换成JavaScript的日期对象。 代码如下: //转换json格式的日期&#xff08;如&#xff1a;{ServerDatetime:"\/Date(1278930470649)\/"}&#xff09;为Javascript的日期对象 fu…

Linux tail 命令

前言 Linux 实时查看日志文件&#xff0c;最主要使用的就是tail命令。 linux tail命令用于显示文件尾部的内容&#xff0c;默认在屏幕上显示指定文件的末尾10行。如果给定的文件不止一个&#xff0c;则在显示的每个文件前面加一个文件名标题。如果没有指定文件或者文件名为“-”…

湿法冶金以及铼提取工艺,湿法冶金工艺特点及工艺流程

湿法冶金是利用浸出剂在一定温度压力下与矿石接触&#xff0c;把矿石中有用的金属溶解后再从溶液中回收有价金属的一种工艺&#xff0c;因为其过程大都是在水溶液中进行&#xff0c;所以又被称为“水法冶金”。 01 湿法冶金工艺特点及工艺流程 湿法冶金作为解决我国金属矿产资…

深度赋能产业数字化转型,蚂蚁集团数字化三件套亮相中国国际金融展

“十四五”规划纲要指出&#xff1a;加快推动数字产业化&#xff0c;推进产业数字化转型&#xff0c;实施“上云用数赋智”行动&#xff0c;推动数据赋能全产业链协同转型。明确提出了通过科技创新&#xff0c;加快产业数字化转型的要求。 4月25日&#xff0c;以“荟萃金融科技…

mybatisPlus·入门·贰

文章目录 1 简单CRUD接口1.1 根据id查询&#xff08;{id传参&#xff09;1.1.1 接口类直接继承IService1.1.2 controller直接调用方法 1.2 根据ids查询1.3 新增1.3.1 接口类直接继承IService1.3.2 controller直接调用方法 1.4 修改状态&#xff08;Query传参&#xff09;1.4.1 …

新版Fluent默认保存的h5文件无法用Tecplot打开的解决办法(亲试有效,评论区是重点)

文章目录 Ansys Fluent简介Fluent 输入/出 文件格式新版Fluent的输出压缩文件&#xff08;.cas.h5文件&#xff09;解决办法 Ansys Fluent简介 Ansys Fluent &#xff0c;是国际上比较流行的商用CFD软件包&#xff0c;在美国的市场占有率为60%&#xff0c;凡是和流体、热传递和…

NetXpert XG2帮您解决“布线安装与维护”难题

在传输大量数据时&#xff0c;光纤变得越来越重要&#xff0c;而铜缆在未来也将继续发挥重要作用&#xff0c;因此我们不仅要比较两种类型布线的优缺点&#xff0c;还要探究光纤传输中的错误来源。 测试光缆传输损耗的准确性对于故障排除至关重要&#xff0c;特别是在光纤情况下…

后台-husky提交代码规范使用

husky是一个git hook工具&#xff0c;可以帮助我们触发git提交的各个阶段&#xff1a;pre-commit、commit-msg、pre-push 1.如何使用husky呢&#xff1f; npx husky-init && npm installWindows安装不成功试试npx husky-init && npm install 2.git commit规范…

Java学习笔记-01

目录 jdk安装及环境配置 java前置知识 编写一个HelloWorld 常量 数据类型 变量 类型转换 算数运算符 一元运算符( --) 关系运算符 逻辑运算符(与或非&#xff0c;逻辑异或) 三元(三目)运算符 Scanner类的简单使用 jdk安装及环境配置 看到的一篇文章&#xff0c;…

【C++STL】set

前言 前面的CSTL的博客&#xff0c;我们介绍了string&#xff0c;vector&#xff0c;list&#xff0c;deque&#xff0c;priority_queue还有stack和queue。 这些容器统称为序列式容器&#xff0c;因为其底层为线性序列的数据结构&#xff0c;里面存储的是元素本身。 而从本节开…

(二)ElasticSearch 辅助工具 Kibana 介绍与安装

1、什么是 kibana &#xff1f; Kibana 是一个针对Elasticsearch的开源分析及可视化平台&#xff0c;用来搜索、查看交互存储在Elasticsearch索引中的数据。使用Kibana&#xff0c;可以通过各种图表进行高级数据分析及展示。 Kibana让海量数据更容易理解。它操作简单&#xff…

0401概述-最短路径-加权有向图-数据结构和算法(Java)

文章目录 1 最短路径2 最短路径的性质3 加权有向图的数据结构3.1 加权有向边3.2 加权有向图 4 最短路径4.1 最短路径API4.2 最短路径的数据结构4.3 边的松弛4.4 顶点的松弛 结语 1 最短路径 如图1-1所示&#xff0c;一幅加权有向图和其中的一条最短路径&#xff1a; 定义&…

加强人工智能共性技术研发与产业化协同发展

央视网消息&#xff1a;“以5G为代表的新一代信息技术与制造业、交通、旅游等实体经济重要领域深度融合。”4月20日下午&#xff0c;国新办举行一季度工业和信息化发展情况新闻发布会&#xff0c;相关部门负责人在答问时表示&#xff0c;将用好融合应用这把金钥匙&#xff0c;开…

基于matlab仿真相控天线阵列在波束成形MIMO-OFDM系统中的使用

一、前言 本例显示了相控阵在采用波束成形的MIMO-OFDM通信系统中的使用。它使用通信工具箱和相控阵系统工具箱中的组件&#xff0c;对组成发射器和前端接收器组件的辐射元件进行建模&#xff0c;用于MIMO-OFDM通信系统。使用用户指定的参数&#xff0c;您可以根据不同空间位置和…

JAVA Future类详解及Thread线程是如何运行Future类的

一、Future基本介绍 Future(java.util.concurrent Interface Future<V>)表示异步计算的结果。Future接口提供了检查计算是否完成、检查计算是否被取消、等待计算完成并获取计算结果等方法。 在并发编程中&#xff0c;我们经常用到非阻塞的模型&#xff0c;但继承thread类…