C语言中的数组并非指针:深入理解数组和指针的区别
前言
在C语言中,数组和指针是两个非常重要的概念,它们在很多方面有着紧密的联系,但也存在显著的区别。尽管数组名有时可以像指针那样使用,但它们本质上并不是一回事。理解这些差异对于编写正确和高效的代码至关重要。本文将深入探讨数组和指针的区别,并提供一些示例代码。

1. 数组与指针的基础概念
- 数组:数组是一系列相同类型数据的集合,它们在内存中连续存储。数组名本身是一个常量,指向数组的起始位置。
- 指针:指针是一个变量,其值为另一个变量的地址。指针可以指向数组中的任何一个元素。
2. 数组与指针的相似之处
尽管数组和指针有很多不同之处,但它们在某些方面确实很相似:
- 数组名作为指针:在许多上下文中,数组名可以被用作指向数组第一个元素的指针。
- 指针算术:指针可以进行算术运算,如
ptr + 1,这同样适用于数组名。
3. 数组与指针的主要区别
现在让我们来看看数组和指针之间的一些关键区别:
3.1 数组名是常量
数组名始终指向数组的起始位置,不能被重新赋值为指向其他位置的地址。
1#include <stdio.h>
2
3int main() {
4 int arr[5] = {1, 2, 3, 4, 5};
5 int *ptr = arr; // arr 被视为指向第一个元素的指针
6
7 printf("Value at arr: %d\n", *arr); // 输出 1
8 printf("Value at ptr: %d\n", *ptr); // 输出 1
9
10 // 下面的代码会导致编译错误
11 // arr = ptr; // 错误:数组名不能被重新赋值
12
13 return 0;
14}
输出:
Value at arr: 1
Value at ptr: 1
解释:
int *ptr = arr;将arr视为指向第一个元素的指针。arr = ptr;导致编译错误,因为数组名不能被重新赋值。
3.2 数组名与指针的类型不同
数组名的类型与指针的类型不同,这在函数参数传递时尤为明显。
1#include <stdio.h>
2
3void printArray(int arr[], int size) {
4 for (int i = 0; i < size; i++) {
5 printf("%d ", arr[i]);
6 }
7 printf("\n");
8}
9
10int main() {
11 int arr[5] = {1, 2, 3, 4, 5};
12
13 printArray(arr, 5); // arr 被传递给函数
14
15 return 0;
16}
输出:
1 2 3 4 5
解释:
void printArray(int arr[], int size)接受一个数组作为参数。printArray(arr, 5);传递数组给函数。
3.3 数组作为函数参数时的退化
当数组作为函数参数时,它会退化为指针,这意味着传递给函数的是数组首元素的地址,而不是整个数组。
1#include <stdio.h>
2
3void printArray(int arr[], int size) {
4 // arr 在这里被视为指针
5 printf("Address of arr in function: %p\n", (void *)arr);
6}
7
8int main() {
9 int arr[5] = {1, 2, 3, 4, 5};
10
11 printf("Address of arr in main: %p\n", (void *)&arr);
12 printArray(arr, 5); // arr 作为指针传递给函数
13
14 return 0;
15}
输出:
1Address of arr in main: 0x7fff5fbff3e0
2Address of arr in function: 0x7fff5fbff3e0
解释:
printArray(arr, 5);传递数组给函数。arr在函数中被视为指向数组第一个元素的指针。
3.4 数组大小的信息丢失
当数组作为函数参数时,编译器不知道数组的实际大小。这可能导致潜在的问题,如越界访问。
1#include <stdio.h>
2
3void printArray(int arr[], int size) {
4 for (int i = 0; i < size; i++) {
5 printf("%d ", arr[i]);
6 }
7 printf("\n");
8}
9
10int main() {
11 int arr[5] = {1, 2, 3, 4, 5};
12
13 printArray(arr, 5); // 正确
14 printArray(arr, 10); // 可能导致越界访问
15
16 return 0;
17}
输出:
11 2 3 4 5
解释:
printArray(arr, 10);可能导致越界访问。
4. 数组与指针的高级用法
数组和指针在高级编程中有着广泛的应用,例如多维数组、指针数组等。
4.1 多维数组与指针
多维数组可以被视为指针数组。
1#include <stdio.h>
2
3void printMatrix(int (*matrix)[3], int rows) {
4 for (int i = 0; i < rows; i++) {
5 for (int j = 0; j < 3; j++) {
6 printf("%d ", matrix[i][j]);
7 }
8 printf("\n");
9 }
10}
11
12int main() {
13 int matrix[2][3] = {{1, 2, 3}, {4, 5, 6}};
14
15 printMatrix(matrix, 2); // 传递多维数组给函数
16
17 return 0;
18}
输出:
1 2 3
4 5 6
解释:
void printMatrix(int (*matrix)[3], int rows)接受一个指针数组作为参数。printMatrix(matrix, 2);传递多维数组给函数。
结论
数组和指针在C语言中有着密切的关系,但它们之间也存在着明显的区别。理解这些差异对于编写正确和高效的代码至关重要。通过上述示例,你应该已经了解了数组和指针之间的主要区别。这种能力对于处理复杂的数据结构和编写更高效的程序非常有帮助。
相关文章:
C语言中的数组并非指针:深入理解数组和指针的区别
前言 在C语言中,数组和指针是两个非常重要的概念,它们在很多方面有着紧密的联系,但也存在显著的区别。尽管数组名有时可以像指针那样使用,但它们本质上并不是一回事。理解这些差异对于编写正确和高效的代码至关重要。本文将深入探…...
Topaz Video AI for Mac 视频无损放大软件安装教程【保姆级,操作简单轻松上手】
Mac分享吧 文章目录 Topaz Video AI for Mac 视频无损放大软件 安装完成,软件打开效果一、Topaz Video AI 视频无损放大软件 Mac电脑版——v5.3.5⚠️注意事项:1️⃣:下载软件2️⃣:安装软件,将安装包从左侧拖入右侧文…...
虚函数和纯虚函数是 C++ 中实现多态性的关键概念
虚函数(Virtual Function) 定义:虚函数是在基类中使用 virtual 关键字声明的函数,目的是允许派生类重写该函数。用途:通过虚函数,基类指针或引用可以调用派生类中重写的函数,从而实现动态多态性…...
计算机网络IP地址分类,子网掩码,子网划分复习资料
IP 地址的概念 IP 地址是独立于硬件地址的逻辑地址,它是由软件提供的地址。 IP 地址是网络层地址。 IP 编址方案和分类 IP 地址由 32 位二进制数构成,分为前缀(网络地址)和后缀(主机地址) 同一网段中每台计算机的 IP 地址是唯一的网络地址的分配全球…...
LINUX下使用SQLite查看.db数据库文件
目录 1. 安装 SQLite 对于 Debian/Ubuntu 系统: 2.安装完成后操作 打开 SQLite 命令行工具并连接到数据库文件 查看表结构 查询表中的数据 执行其他 SQL 操作 3. 退出 SQLite 命令行工具 4. 使用图形化工具(可选) 总结 在 Linux 环…...
基于uniapp微信小程序的校园二手书交易系统
作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏:…...
性能测试中的操作系统参数优化
目录 以下是一些针对性能测试的操作系统优化建议 关闭不必要的服务和程序: 更新系统和驱动程序: 优化电源管理设置: 调整内存配置: 网络配置优化: 磁盘I/O优化: 内核参数调整: 安全软件…...
rabbitmq高级特性(2)TTL、死信/延迟队列、事务与消息分发
目录 1.TTL 1.1.设置消息过期时间 1.2.设置队列过期时间 2.死信队列 2.1.介绍 2.2.演示 3.延迟队列 3.1.模拟实现延迟队列 3.2.延迟队列插件 4.事务与消息分发 4.1.事务 4.2.消息分发 1.TTL 所谓的ttl,就是过期时间。对于rabbitmq,可以设置…...
了解一下,RN中怎么加载 threejs的
在React Native(RN)中加载和使用Three.js,一个流行的3D图形库,通常需要一些额外的步骤,因为Three.js主要是为Web浏览器设计的,而React Native则使用原生的渲染引擎。不过,有一些方法可以在React…...
笔记整理—linux驱动开发部分(1)驱动梗概
驱动可以分为广义上的和狭义上的驱动。广义上的驱动是用于操作硬件的代码,而狭义上的驱动为基于内核系统之上让硬件去被操作的逻辑方法。 linux体系架构: 1.分层思想 :在OS中间还会有许多层。 : 2.驱动的上面是系统调用(API&…...
金融领域中的敏感性分析和期权价值计算相关的操作
代码主要进行了金融领域中的敏感性分析和期权价值计算相关的操作。首先通过一系列方程求解S3和S2的值,然后基于这些值以及给定的参数计算一些中间变量(a1、a2、a3、b1、b2、b3),最后利用多元正态分布函数(mvncdf)和一元正态分布函数(normcdf)计算期权价值C、净现值(NP…...
GraphQL系列 - 第1讲 GraphQL语法入门
目录 一、介绍GraphQL二、GraphQL基本使用方法三、Schema 定义语言 (SDL)3.1 类型定义1)对象类型2)标量类型3)枚举类型4)输入类型5)列表类型6)非空类型7)接口类型8)联合类型 3.2 查询…...
015:地理信息系统开发平台ArcGIS Engine10.2与ArcGIS SDK for the Microsoft .NET Framework安装教程
摘要:本文详细介绍地理信息系统开发平台ArcGIS Engine10.2与ArcGIS SDK for the Microsoft .NET Framework的安装流程。 一、软件介绍 ArcGIS Engine 10.2是由Esri公司开发的一款强大的GIS(地理信息系统)开发平台。该软件基于ArcGIS 10.2 fo…...
Android——显式/隐式Intent
概述 在Android中,Intent是各个组件之间信息通信的桥梁,它用于Android各组件的通信。 Intent 的组成部分 一、显式 Intent 第一种方式 Intent intent new Intent(this, ActFinishActivity.class);startActivity(intent);第二种方式 Intent intent …...
【鸿蒙HarmonyOS实战:通过华为应用市场上架测试版App实现HBuilder X打包的UniApp项目的app转hap教程(邀请码)方式教程详解】
鸿蒙HarmonyOS实战:通过华为应用市场上架测试版App实现HBuilder X打包的UniApp项目的app转hap教程(邀请码)方式详解 在使用uniapp打包的鸿蒙项目的过程中,由于生成的是app文件,而hdc传给鸿蒙HarmonyOS系统需要的是hap文…...
一篇文章入门傅里叶变换
文章目录 傅里叶变换欧拉公式傅里叶变换绕圈记录法质心记录法傅里叶变换公式第一步:旋转的表示第二步:缠绕的表示第三步:质心的表示最终步:整理积分限和系数 参考文献 傅里叶变换 在学习傅里叶变换之前,我们先来了解一…...
基于python的语音识别与蓝牙通信的温控系统
基于python的语音识别与蓝牙通信的温控系统毕设项目 大家好,我是陈辰学长,一名在 Java 圈辛勤劳作的码农。今日,要和大家分享的是一款基于python的语音识别与蓝牙通信的温控系统毕设项目。项目源码以及部署相关事宜,请联系陈辰学…...
Pandas Series学习
1.Series简介 Pandas Series类似表格的列(column),类似于一维数组,可以保存任何数据类型,具有标签(索引),使得数据在处理分析时更具灵活性。Series数据结构是非常有用的,…...
为什么要探索太空?这对我们有什么好处?
几个世纪以来,人类一直着迷于宇宙的奥秘,这驱使我们冒险离开地球,去探索太阳系之外的未知环境。在当今世界,我们为什么要进行太空探索之旅这个问题,远不止出于单纯的好奇。 归根结底,太空探索是一种必要之…...
uniapp开发【选择地址-省市区功能】,直接套用即可
一、效果展示 二、代码 <template><view><view class="user_info"><view class="item"...
LOSEHU固件深度解析:泉盛UV-K5/K6全功能固件架构与实战部署指南
LOSEHU固件深度解析:泉盛UV-K5/K6全功能固件架构与实战部署指南 【免费下载链接】uv-k5-firmware-custom 全功能泉盛UV-K5/K6固件 Quansheng UV-K5/K6 Firmware 项目地址: https://gitcode.com/gh_mirrors/uvk5f/uv-k5-firmware-custom LOSEHU固件是一款专为…...
3个步骤解决经典游戏无法联网:IPXWrapper终极兼容方案
3个步骤解决经典游戏无法联网:IPXWrapper终极兼容方案 【免费下载链接】ipxwrapper 项目地址: https://gitcode.com/gh_mirrors/ip/ipxwrapper 你是否曾在Windows 10或11系统上试图重温《红色警戒2》、《帝国时代》或《星际争霸》的局域网对战,却…...
5G双连接(EN-DC):开启5G网络融合新体验
5G双连接(EN-DC):开启5G网络融合新体验 在5G网络快速发展的进程中,5G双连接(EN-DC)技术逐渐成为行业内关注的焦点。它作为5G网络架构中的一项关键技术,为提升网络性能、优化用户体验发挥着重要作…...
ARM架构计数器-定时器寄存器原理与应用
1. ARM架构中的计数器-定时器寄存器深度解析在ARM处理器架构中,计数器-定时器寄存器是实现精确时间控制和事件触发的核心组件。这些寄存器不仅为操作系统提供时间基准,还在虚拟化、安全扩展和实时系统中扮演关键角色。本文将深入剖析CNTHCTL和CNTHP_CTL等…...
Android虚拟定位终极指南:无需Root的应用级位置伪装解决方案
Android虚拟定位终极指南:无需Root的应用级位置伪装解决方案 【免费下载链接】FakeLocation Xposed module to mock locations per app. 项目地址: https://gitcode.com/gh_mirrors/fak/FakeLocation 你是否遇到过这样的困扰:想在游戏中签到获取限…...
企业级AI低代码平台kweaver-dip:架构解析与工作流实战
1. 项目概述:一个面向企业级AI应用开发的低代码平台 最近在和一些做企业数字化转型的朋友聊天,大家普遍提到一个痛点:AI能力很强,但想把它真正用起来,门槛实在太高了。不是每个团队都有能力养一支算法工程师队伍&#…...
2026英文论文降AI实战SOP:保留原格式,4招把AIGC率从97%压到8%
大家最近都在为英文降aigc率发愁吧,作为研三党,我太懂这种痛了,之前我自己写英文初稿,写完直接拿去查重,结果turnitin检测ai率飙到了89%,当时看着报告整个人都懵了。 怎么给英文降ai?对于非母语…...
GitHub中文化插件终极实战指南:5分钟实现高效中文开发体验
GitHub中文化插件终极实战指南:5分钟实现高效中文开发体验 【免费下载链接】github-chinese GitHub 汉化插件,GitHub 中文化界面。 (GitHub Translation To Chinese) 项目地址: https://gitcode.com/gh_mirrors/gi/github-chinese GitHub作为全球…...
【c++面向对象编程】第3篇:类与对象(二):构造函数与析构函数
目录 一、一个让人头疼的问题 二、构造函数:对象出生时的“第一声啼哭” 1. 最基本的构造函数 2. 带参数的构造函数(重载) 3. 初始化列表:更高效的初始化方式 三、默认构造函数:那个“看不见”的函数 四、析构函…...
App安全测试实战:OWASP ZAP 2.8 代理配置进阶与场景化应用
1. OWASP ZAP 2.8代理配置的核心价值 如果你做过移动应用安全测试,一定遇到过这样的困境:抓不到HTTPS流量、内网环境难以调试、自动化测试时代理频繁断开。这些问题看似简单,实际会浪费大量时间在环境搭建上。我在去年的一次金融App测试中&am…...
