深度剖析C/C++中数组名与指针的详细区别

C++引用深度剖析 C++引用的前生今世:引用深度剖析 阅读详情

一、数组名的运算与指针并不是完全相同。

这是最明显的例子,指针支持自增、自减运算,但是数组名并不支持自增、自减运算。其实这么做的原因也很简单,由于数组是一片连续的空间,需要一个类似于指针的东西指向这一片连续空间的首地址。由于在整个内存中对于某个个数组只有唯一的数组名,假如可以对数组名进行自增、自减运算,那么当我们下一次使用这个数组名时并不知道这个数组名是否是指向的该片连续内存的首地址,这时就会导致内存管理的混乱。因此严禁对数组名进行自增、自减操作。

二、把数组名当作参数传递给函数时数组名会退化成真正的指针。

考虑下面代码及其输出:

/* 
 * 输出: 
 * arr: 40
 * ptr: 8
 * ptr2: 8
 * int*: 8
 * func: 8
 */

#include <iostream>
 
using namespace std;

void func(int arrCpy[]) {
    printf("func: %lu\n",sizeof(arrCpy));
}

int main() {
    int arr[10];
    int (*ptr)[10] = &arr;
    int *ptr2 = arr;
    printf("arr: %lu\n",sizeof(arr));
    printf("ptr: %lu\n",sizeof(ptr));
    printf("ptr2: %lu\n",sizeof(ptr2));
    printf("int*: %lu\n",sizeof(int*));
    func(arr);
    return 0;
}

我们来逐行分析:

1、对于sizeof(arr),如果arr真的是一个指针,那么sizeof的输出应该是指针长度8(我的电脑是mac,长度由sizeof(int*)得出),而并不是整个数组的长度40。

2、对于ptr和ptr2来说,ptr是一个指针数组,ptr2是一个普通的int指针。对于&arr这个语句,编译器会自动将它转换为&arr[0]来获取 第一个元素的首地址。如果在并未对ptr和ptr2进行操作之前进行打印,你会发现数组指针的值竟然就是首个元素的地址!貌似ptr与ptr2没有任何区别啊???

//输出:
//ptr address: efbff5a0
//ptr2 address: efbff5a0   
    
printf("ptr address: %x\n",ptr+1);
printf("ptr2 address: %x\n",ptr2+1);

但是如果分别对ptr和ptr2加1之后再输出地址这个问题的答案就出来了~

//输出:
//ptr address: efbff5c8
//ptr2 address: efbff5a4   
    
printf("ptr address: %x\n",ptr+1);
printf("ptr2 address: %x\n",ptr2+1);

读者可以自己算一下这两个16进制换成十进制相差多少。这里我算出来了,两者正好相差36!而整个数组的长度正好是40且一个单元的长度为4。所以我们得出结论:数组指针指向的是整个数组,在对数组指针进行+1操作后该指针会直接指向数组整个连续的内存看空间的下一个地址(也就是ptr越过了arr这个数组的所有的10个内存单元)。而ptr2就是一个普通的整形数组,+1只会指向下一个内存单元(arr[1])。

3、第三个例子是重中之重!函数里的sizeof(arrCpy)为什么输出的是指针长度不是数组长度???我明明是传入的数组啊!这是就是因为把数组名当作参数传递给函数时数组名会退化成真正的指针!所以这牵扯出来了一个与memeset函数有关的问题:

//输出:
//-1 -1 0 0 0 0 0 0 -272632344 32766
void init(int* arrCpy) {
    memset(arrCpy, -1, sizeof(arrCpy));
    for(int i = 0; i< 10;++i) {
        cout << arrCpy[i] << endl;
    }
}

为啥只用前两个元素初始化成功了??原因很简单,当数组名退化为指针后,长度与一个int型指针长度一致,为8个字节。而一个int正好是4个字节且该数组存储的元素全部为int型。因此4*2=8只有前两个元素被=初始化了。

一般来说,并不建议传参进行memset初始化,因为如果是新手的话这些问题根本发现不了会产生迷之的错误。如果非要在函数中使用memset初始化数组,那么memset的最后一项一定要写为sizeof(type)*num的形式:

//输出:
//-1 -1 -1 -1 -1 -1 -1 -1 -1 -1
void init(int* arrCpy) {
    memset(arrCpy, -1, sizeof(int)*10);
    for(int i = 0; i< 10;++i) {
        cout << arrCpy[i] << endl;
    }
}

只有这样才能成功的对数组进行初始化。

 

C和C++中数组名与指针的区别.pdf 对C/C++中数组名与指针从多角度进行比较分析,通过具体实例充分论证了二者的不同. 立即下载

相关推荐

C/C++数组名与指针区别深层探索

1.    引言   指针是C/C++语言的特色,而数组名与指针有太多的相似,甚至很多时候,数组名可以作为指针使用。于是乎,很多程序设计者就被搞糊涂了。而许多的大学老师,他们在C语言的教学过程中也错误得给学生讲解:“数组名就是指针”。很幸运,我的大学老师就是其中之一。时至今日,我日复一日地进行着C/C++项目的开发,而身边还一直充满这样的程序员,他们保留着“数组名就是指针”的误解。   想必这种误解的根源在于国内某的C程序设计教程。如果这篇文章能够纠正许多中国程序员对数组名和指针的误解,笔者就不甚欣慰了。借此文,笔者站在无数对知识如饥似渴的中国程序员之中,深深寄希望于国内的计算机图书编写者

C/C++ 知识点:指针与数组名区别

从输出结果可以看出来,sizeof()的结果是4,说明此时的数组名是一个普通指针。

个人技术博客 348

永磁同步电机控制笔记:foc控制原理通俗讲义

引言 到此为止,永磁同步电机控制相关文章已经写了7篇,其中simulink仿真系列文章5篇,控制笔记系列文章2篇,恍惚间感觉少了一篇概论,在此插入一篇,也算是对入坑电机控制一年半来的知识梳理。 文章目录引言一、同步电机是怎么转起来的二、什么样的旋转磁场效率最高三、怎么精准控制旋转磁场的方向四、怎样调节dq轴电流 一、同步电机是怎么转起来的 永磁同步电机结构如下: 外围是定子绕组,中间为永磁体,设...

搞电机的博客 2万+

C++中数组和指针的关系(区别)详解

C++中数组和指针的关系(区别)详解 本文转自:http://c.biancheng.net/view/1472.html 博主在阅读后将文中几个知识点提出来放在前面: 没有方括号和下标的数组名称实际上代表数组的起始地址,这意味着数组名称实际上就是一个指针。 在数学语句中使用指针时,它不像常规变量那样工作。 向指针添加值时并要解引用时,括号非常重要。 array[index] 相当于 *(array + index)。 C++ 不会对数组执行边界检查。 不仅指针符号可以与数组名称一起使用,而且下标符号也可

weixin_44966641的博客 2788

智慧工地算法视频分析服务器区域入侵检测AI视频分析技术在煤矿的实战应用

通过实时分析和处理井下视频资料,智慧矿山算法视频分析服务器不仅能够及时发现并预警人员违规行为和设备异常状况,还能够通过智能分析预防潜在的安全风险,从而显著提高煤矿的安全管理水平和生产效率。

EasyDarwin开源社区技术博客 560

MIT Mini Cheetah--仿真流程

MIT Mini Cheetah–仿真 摘要 由于官方提供代码中,控制仿真环境中的猎豹机器人运动需要遥控器来控制。官方默认推荐使用logitech Gamepad F310游戏手柄:We use the Logitech F310 controller. There’s a switch in the back, which should be in the “X” position. The controller needs to reconnected if you change the switch

Galaxy_Robot的博客 5916

c++指针和数组名的区别

1.数组名是指向数组首个元素地址的指针,不可改变其指向的位置,即数组名只可指向数组的首个元素。 而指针可以改变指向第几个元素,如 int*a=new double [10]; int b[10]={1}; a[0]=0; a[1]=1; a[2]=2; a[3]=3; a=a+2;//指针可以这样操作 b=b+2;//此处报错,数组名不可改变 其指向的地址 2.每当用到数组名这个指针的时候,系统都会传入数组的信息,而普通的指针只是一个4字节的整数 cout<<sizeof(a)<<

qq_39042392的博客 302

把对讲门铃(控制底楼铁门)接入米家服务器

今天讲个跟SDR或者无人机无关的东西,技术含量不高,但是方便了我的生活。 现在家门有智能锁,汽车也可以远程解锁发动,NFC门禁也可以用某些手机复制,唯独楼下的铁门,必须用老式对讲门铃控制。 也就是说其它钥匙都可以不带,就剩这个钥匙还必须随身携带。 另外有时候人不在家,不能开楼下铁门,快递员也没法把东西送上楼。 ......

老邵的开源世界 6551

6. C++数组名与指针区别

1. C++数组名与指针区别 对比 数组名 指针 &(取地址) 数组名取地址得到的是数组名所指元素地址(数组首地址) 对指针取地址得到的是指针变量自身的地址 常量变量 数组名师常量指针 指针是变量指针 sizeof 对数组名使用sizeof时,得到的是元素个数乘元素类型的字节数 对指针sizeof得到的是指针类型的字节数 1.1数组名是常量指针 数组名是常量指针,不可以被修改,指针是变量指针,可以修改 #include <iostream> using nam

qq_35123107的博客 997

手把手教你用PlantVillage数据集搭建农作物病害识别模型(Python实战)

本文详细介绍了如何使用PlantVillage数据集和Python构建农作物病害识别模型。从环境准备、数据获取到模型构建、训练与评估,手把手教你实现一个实用的农业AI应用。特别针对PlantVillage数据集的特点,提供了处理类别不平衡、图像预处理和模型优化的实战技巧,帮助开发者快速掌握农作物病害识别技术。

weixin_29184371的博客 479

Open3D 曲率下采样

曲率下采样是一种基于几何特征的点云处理技术,通过计算每个点的曲率来判断其所在位置的局部表面特征,从而进行选择性保留。曲率的计算通常基于点的法向量和其邻域点的分布。

纵马踏花向自由 841

C/C++数组名与指针区别

C/C++数组名与指针区别 1)数组名的内涵在于其指代实体是一种数据结构,这种数据结构就是数组; 2)数组名的外延在于其可以转换为指向其指代实体的指针,而且是一个指针常量; 3)指向数组的指针则是另外一种变量类型(在WIN32平台下,长度为4),仅仅意味着数组的存放地址! 4)数组名作为函数形参时,在函数体内,其失去了本身的内涵,仅仅只是一个指针;在失去其内涵的同时,它还失去了其常量特性,

我的读书笔记(2011-2013) 640

小孙学变频学习笔记(二)变频器的逆变电路

本文主要介绍了变频器中逆变电路的核心器件IGBT及其应用。IGBT是一种电压控制型三端半导体开关器件,具有开关频率高、功耗低的优点,在变频器中仅使用截止和饱和导通状态。文章详细分析了IGBT的结构特性、与晶闸管的区别,以及由四个IGBT组成的直流转交流逆变电路原理。重点阐述了IGBT并联反向二极管的作用:提供电流反向通路、避免反向电压损坏器件、提高开关效率等。最后提供了相关学习参考网址供读者进一步研究。

qq_43091070的博客 1196

深度剖析指针的进阶——C语言的进阶篇

大家好我是沐曦希💕 文章目录💫前言2.字符指针练习3.指针数组数组指针数组指针的定义&数组名VS数组名数组指针的使用数组参数、指针参数一维数组传参二维数组传参一级指针传参二级指针传参4.写在最后 💫前言 指针的概念: 指针就是个变量,用来存放地址,地址唯一标识一块内存空间。 指针的大小是固定的4/8个字节(32位平台/64位平台)。 指针是有类型,指针的类型决定了指针的±整数的步长,指针解引用操作的时候的权限。 指针的运算。 指针又分为字符指针,整型指针,函数指针,数组指针等。 ch.

m0_68931081的博客 1032

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

C进阶——深度剖析指针

本文深度解剖C中指针的重难点内容 让你的指针不再是问题

theonly_Love的博客 278

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

C++数组名内涵深度剖析

指针是C/C++语言的特色,而数组名与指针有太多的相似,甚至很多时候,数组名可以作为指针使用。于是乎,很多程序设计者就被搞糊涂了。而许多的大学老师,他们在C语言的教学过程中也错误得给学生讲解:"数组名就是指针"。很幸运,我的大学老师就是其中之一。时至今日,我日复一日地进行着C/C++项目的开发,而身边还一直充满这样的程序员,他们保留着"数组名就是指针"的误解。 数组名的正常使用 首先我要跟大家

tangliguantou的专栏 1025

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

深度剖析指针(下)——“C”

是你们心心念念的指针噢

weixin_74957752的博客 1875

深度剖析指针(上)——“C”

是你们心心念念的指针呀

weixin_74957752的博客 1467

【C语言】深度剖析指针(二):指针与数组,字符,函数的深度关联

本文围绕数组与指针的关联展开,解析了数组名的一般含义与特殊情况,以及如何用指针访问数组。阐述了一维和二维数组传参本质,介绍了冒泡排序实现。还讲解了二级指针、指针数组、字符指针、数组指针、函数指针及函数指针数组的定义、初始化、使用及相关应用,如指针数组模拟二维数组、函数指针数组实现转移表简化多分支逻辑等。

记录了从0学习Java技术栈的日常 1874

【C语言】深度剖析指针(三):回调机制、通用排序与数组指针逻辑

本文围绕C语言中的回调函数、qsort函数、sizeof与strlen的区别及数组与指针笔试题展开。介绍了回调函数的定义、应用及优势;详解qsort函数的参数、用法、模拟实现;对比sizeof与strlen的特性;通过多个代码示例解析数组与指针相关笔试题,助读者掌握这些关键知识点。

记录了从0学习Java技术栈的日常 1083

【C语言深度剖析】详解strlen与sizeof的区别及用法

文章目录含义示例一示例二说明代码三代码四总结 关于 strlen 与 sizeof 的区别,我相信很多人都有所了解 以下我深度解析一下strlen 与 sizeof的区别和注意事项 含义 sizeof()是运算符,在头文件的类型为unsigned int,其运算值在编译时就计算好了,参数可以是指针、数组、类型、对象和函数等; strlen()是函数,要在运行时才能计算。参数必须是字符型指针(char*)。当数组名作为参数传入时,实际上数组就退化为指针了。该函数完成的功能是从代表该字符串的第一个地址开始遍历的

Edison's 小宇宙 1442

指针进阶深度剖析

深度剖析和指针进阶

weixin_55079859的博客 200

《C语言深度解剖》(10):数组指针、指针数组和数组指针数组

数组指针是什么?指针数组是什么?指针跟数组有什么关系?指针数组是指针还是数组?数组的类型你真的理解吗?二维数组和一维数组的关系;数组传参和指针传参。

更新C/C++,数据结构与算法,计算机视觉,深度学习,目标检测 1296

详解C语言指针(上):(含大厂面试实战哦!)指针运算、指针和数组、多级函数

🔥🍉⭐️。

艾莉丝努力练剑的博客,感谢大家一直以来的对艾莉丝的支持和鼓励,uu们如果对C/C++方向感兴趣的话,可以通过艾莉丝主页的微信名片加艾莉丝的好友,和努力练剑的艾莉丝一起加油! 1157

深入解析C/C++多级指针:从内存模型到动态二维数组实战

指针是C/C++编程中直接操作内存的核心机制,它通过存储变量地址实现了高效的数据共享与传递。其原理在于利用内存地址的间接访问,解引用操作符(*)用于获取或修改目标数据。这一技术价值在于避免了不必要的数据拷贝,显著提升了程序性能,尤其在系统编程和底层优化中至关重要。应用场景广泛,包括动态内存管理、函数间参数传递以及复杂数据结构(如链表、树)的实现。本文聚焦于多级指针这一高级主题,通过剖析**动态创建二维数组**和**在函数中修改指针本身**等典型应用,结合内存模型图解与常见错误排查,帮助开发者掌握其正确用法与

weixin_34082789的博客 378
上一篇: 《OSTEP》读书笔记 虚拟化(3)调度算法
下一篇: servletConfig与servletContext
donCoder
博客等级 码龄9年 65粉丝 79原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值