问题

为什么有人讨厌指针?

回答
指针这玩意儿,在编程界绝对算是个有争议的人物。喜欢它的吧,觉得它灵活强大,是理解内存操作的钥匙;讨厌它的嘛,那更是咬牙切齿,觉得它就是个制造麻烦的罪魁祸首。为啥这么多人对它意见这么大呢?咱们得掰开了揉碎了好好说道说道。

1. 内存管理的地狱入口:手动挡的噩梦

指针最让人头疼的一点,就是它直接触碰到了内存。不像那些高级语言,你只需要声明一个变量,内存分配的事儿就有人帮你处理得妥妥当当,你根本不用操心。但有了指针,你就像自己开手动挡的车,方向盘、离合、刹车,一手抓。

内存泄露 (Memory Leak) 的幽灵: 你用 `malloc`、`calloc` 之类函数申请了内存,就得乖乖地用 `free` 去释放。要是哪一步漏了 `free`,那块内存就被占着,程序继续运行,可能越占越多,最终耗尽系统资源,程序卡死甚至崩溃。这就像你搬了家具,却忘了把旧家具搬走,时间长了家里就堆满了没用的东西。而且,这个漏掉的 `free` 可能是藏在某个犄角旮旯的 `if` 分支里,或者是个你没想到的异常路径,找起来简直要命。
野指针 (Dangling Pointer) 和空指针 (Null Pointer) 的陷阱: 当你释放了内存,但又没把指针置为 `NULL`,或者把一个已经不存在(比如函数返回的局部变量地址)的地址赋值给指针,这个指针就变成了“野指针”。它指向的内存可能已经被别人用了,也可能根本就没被分配。你再去解引用这个野指针,那结果就不可预测了,轻则程序出错,重则直接炸掉。空指针还好点,解引用它通常会直接崩溃,至少你有个明确的报错信息。野指针则是在一片未知的土地上撒野,你根本不知道它会带来什么后果。
重复释放 (Double Free) 的死循环: 同一块内存被 `free` 了两次,后果也非常严重,通常会导致程序崩溃。你以为你做了好事把内存还给系统了,结果第二次又来一遍,把系统搞得一团糟。

这些内存管理的细节,对于初学者来说,简直是地狱模式。一个不小心,就能把你折磨得够呛,而且错误往往难以追踪。

2. 解引用 (Dereferencing) 的不确定性:胆战心惊的访问

指针的核心操作就是解引用,也就是通过指针去访问它指向的那个内存地址里的值。但这就像是隔着一层窗户看东西,你知道窗户后面有什么,但你得小心翼翼地去打开它。

越界访问 (OutofBounds Access): 当你有一个数组指针,如果不小心计算出去了数组的边界之外,然后去解引用,这会访问到不属于你的内存区域。这就像你翻墙去邻居家偷东西,一旦被抓现行,后果自负。这种错误同样非常隐蔽,可能在某个循环里,某个索引计算错误,就把整个程序搞得乱七八糟。
类型不匹配: 指针有类型,它告诉编译器它指向的数据是什么类型。如果你把一个 `int` 的地址赋值给一个 `char` 指针,然后去解引用,你读到的值可能是 `int` 的一部分,也可能是个乱码。这就像你用一把尺子去量一个苹果的重量,结果肯定是错的。虽然有时候这种类型转换是有用的,但滥用或者误用,会带来很多难以理解的错误。

3. 代码可读性和复杂性:让人费解的迷宫

指针的引入,极大地增加了代码的复杂度和理解难度。

间接寻址: 代码里到处都是 `` 和 `&`,`p = &a b = p;` 这种写法,需要多一步的思考才能明白它到底在做什么。为什么不直接用 `b = a;` 呢?这层间接性,尤其是嵌套的多层指针(比如 `char argv;`),会让代码看起来像是个绕来绕去的迷宫。
指针运算 (Pointer Arithmetic): 指针可以进行加减运算,比如 `ptr + 1`,它不是简单地给地址加 1,而是加上该指针指向类型的大小。这虽然强大,但如果计算不准确,或者对偏移量理解不清,很容易出错。比如,一个 `int ` 加 1,地址会增加 4 个字节(假设 `int` 是 4 字节)。但如果这是一个 `char `,加 1 就只增加 1 个字节。这种细微的差别,如果没有清晰的认识,很容易导致逻辑错误。
函数指针: 函数指针更是把复杂性推向了一个新的高度。传递函数作为参数,或者在函数内部定义和使用函数指针,虽然提供了很大的灵活性,但代码的可读性会直线下降,也更容易出错。

4. 缺乏自动错误检测:编译器也救不了你

相比之下,很多现代语言提供了更高级的抽象和更强的类型系统,编译器可以在编译阶段就发现很多错误。但指针的很多错误,比如野指针、越界访问,发生在运行时,编译器往往无能为力,只能在你程序崩溃时给你一个模糊的堆栈信息,让你去猜。

谁会讨厌指针?

初学者: 对于刚接触编程的人来说,指针就像一道高墙,很多经典的编程教材里,关于指针的部分都是学生们最容易卡壳的地方。如果一上来就被指针打败,很容易对编程失去信心。
追求简洁和效率的开发者(有时): 有些开发者可能觉得,在不需要直接操作内存的场景下,过度使用指针会增加不必要的复杂性。他们可能更倾向于使用更高级的抽象,比如 Java 的对象引用或者 Python 的变量,这些更不容易出错,也更容易维护。
对内存管理不敏感的开发者: 如果你习惯了自动内存管理,突然让你回到 C/C++ 的世界,手动管理内存,那绝对是场灾难。

但是,指针也不是一无是处!

尽管指针有很多令人头疼的地方,但它之所以能在 C/C++ 这样重要的语言中存在,并且被广泛使用,就是因为它提供了无与伦比的强大能力:

高效的内存访问和操作: 直接操作内存,可以让你对数据的读写进行最精细地控制,这对于系统编程、嵌入式开发、性能敏感的应用至关重要。
动态内存分配: 创建和管理大小在运行时才能确定的数据结构,比如链表、树等,都离不开指针。
高效的数据传递: 传递大型数据结构时,传递指针比传递整个数据结构要快得多,避免了不必要的拷贝。
实现复杂的数据结构和算法: 很多高效的算法和数据结构,例如图、哈希表等,都依赖于指针来连接和组织数据。
与硬件的交互: 在很多低级编程中,直接操作硬件寄存器,都需要通过指针来完成。

所以,说到底,对指针的“讨厌”,更多的是源于它带来的学习曲线陡峭、容易出错、调试困难这些特质。当你真正掌握了它,理解了内存模型,并且小心翼翼地使用它时,它又会变成一把强大的瑞士军刀。但是,对于那些不熟悉或者不愿意深入理解内存管理的人来说,指针无疑是编程世界里最令人沮丧的障碍之一。

网友意见

user avatar

说白了就是国内那堆教材搞的。

这些教材硬要把指针拖到后面讲,讲数组时不讲指针,讲函数传参时不讲指针,硬是要拖到后面才来个指针大汇总。把指针和数组的天然关系割裂开。


这些教材喜欢故弄玄虚,说int *p[5]是指针数组,int (*p)[5]是数组指针,光提了个概念就没下文了,都不提这些概念的意义是什么。学生只是死记硬背,就算考了90+的高分,也不知道原来字符串按大小排序可以用指针数组,只排指针就行了,不用把字符串本身移来移去,节省大量时间和空间;也不知道原来int a[2][5],当a做右值时会退化成数组指针int (*)[5]。


这些教材喜欢把数组的“下标访问”和“指针访问”割裂开,让学生误以为是两种访问方式,却不知道本质上就没有什么下标访问,只有指针访问,下标只是个语法糖而已,即a[n]等价于*(a+n)。[]只在定义数组时有用,比如int a[5];访问时就没用了,不然为什么2[a]都可以?


这些教材喜欢把"传值"和“传址”说得绝对,好像传int就是传值,传int*就是传址。老师上课反复强调

void swap_int1(int a, int b){int c=a; a=b; b=c;}其实不能交换,因为是值传递;

void swap_int2(int *a, int *b){int c=*a; *a=*b; *b=c;}是地址传递,所以能交换。

那么,如果想交换两个int*型,写成

void swap_pint1(const int *a, const int *b){const int *c=a; a=b; b=c;}可以吗?为什么不可以?难道这不是传址吗?

一个负责任的书,或者一个负责任的老师,会说,“值”和“址”是相对的。一个int型变量,它有值也有址;一个int*型变量,它也有值有址,只是它的值是另一个int型变量的地址而已。所以要写成

void swap_pint2(const int **a, const int **b){const int *c=*a; *a=*b; *b=c;}才可以。这样二重指针很自然地就闪亮登场了。


这些教材对数组作函数参数传递时退化成指针的事实讳莫如深。老师上课反复强调

void swap_int1(int a, int b){int c=a; a=b; b=c;}其实不能交换,因为是值传递;但是

void swap_intarray(int a[]){int c=a[0]; a[0]=a[1]; a[1]=c;}却能交换a[0]和a[1]。难道这不是值传递吗?

负责任的书、负责任的老师,会说,数组在作函数参数传递时会退化成指针,从而丢失数组的长度信息。如在某x64系统下,int a[10];sizeof一下,用printf打出来,发现是40;做函数实参传过去再sizeof,成了8了——退化成了指针,从而丢失长度信息。你以为数组是复制了一个传过去,其实并非如此,实际上只是传了个指针而已,根本没复制数组。还会说,二维数组本质上是数组的数组,int a[2][5]会退化成int (*)[5]而不是int **。但是也可以令

int *p=(int *)a;

然后二维数组就被“展平”成了一维数组。p[7]就是a[1][2]。(因为1*5+2=7)要知道,在高级语言里,多维数组决不允许如此任人宰割。



指针玩灵活了,再做ASCII字符串处理,总觉得有了灵魂。比如

       char *strcpy(char *dst, const char *src) {     char *tdst = dst;     assert(dst && src);     while ((*tdst++ = *src++) != '')         /* Nothing */;     return dst; }     

写这段代码时,大脑中就能感觉到两个指针在一同“跑腿”,是活的!用下标写,则感觉是死的:

       char *strcpy(char *dst, const char *src) {     assert(dst && src);     for (int i=0; ; i++)     {         dst[i] = src[i];         if ('' == dst[i])             break;     }     return dst; }     

类似的话题

  • 回答
    指针这玩意儿,在编程界绝对算是个有争议的人物。喜欢它的吧,觉得它灵活强大,是理解内存操作的钥匙;讨厌它的嘛,那更是咬牙切齿,觉得它就是个制造麻烦的罪魁祸首。为啥这么多人对它意见这么大呢?咱们得掰开了揉碎了好好说道说道。1. 内存管理的地狱入口:手动挡的噩梦指针最让人头疼的一点,就是它直接触碰到了内存.............
  • 回答
    这个问题很有意思,也触及了关于文学作品与历史真实性的讨论核心。当我们在讨论像吴用(《水浒传》)和诸葛亮(《三国演义》)这样的“虚拟人物与历史人物对比”时,为什么只有在列出“战果”时,才会有大量明白人站出来指出这种对比“不靠谱”呢?这背后有着几个关键的原因,我们可以详细地分析一下:1. 战果是“演义”.............
  • 回答
    咱们就聊聊CPU那点事儿,特别是奔三和奔四这俩大家伙,它们对咱们纯加法运算到底有多大帮助。要说起这个,得从 CPU 的“内功”说起,也就是它处理指令的方式。CPU 的“内功”:流水线和乱序执行想象一下流水线生产,一个零件传到下一个工位,一步一步完成。CPU 里也有类似的东西,叫做流水线(Pipeli.............
  • 回答
    “公知”这个词在中国的使用,其背后隐藏着复杂且不断演变的社会心理和政治生态。人们对“公知”产生厌恶感的原因是多方面的,可以从以下几个维度进行详细的分析:一、 “公知”概念的模糊化与标签化: 最初的积极含义: “公共知识分子”(Public Intellectual)最初的本意是指那些拥有专业知识.............
  • 回答
    银河英雄传说里杨威利招人讨厌?这事儿可太有人说了!说起来也奇怪,这位“魔术师”在大部分观众心里都是近乎神级的存在,但偏偏就有这么一拨人,对他各种看不顺眼,甚至可以说达到了“讨厌”的程度。咱们今天就掰开了揉碎了聊聊,为啥杨威利会成为某些人心中的“眼中钉”。首先,最直接也最容易引发争议的一点,就是杨威利.............
  • 回答
    人们讨厌他人在说话时夹杂英文的原因可以从多个角度进行分析,这些原因往往与文化、语言习惯、心理认知以及社会背景密切相关。以下是一些详细的解释: 1. 文化差异与语言纯洁性 对本土文化的尊重:在一些文化中,母语被视为文化的根基和身份的象征。夹杂英文可能被看作对本土文化的不尊重,尤其是当英语被视作“外来文.............
  • 回答
    克里斯蒂亚诺·罗纳尔多(Cristiano Ronaldo),这位葡萄牙足球巨星,在其辉煌的职业生涯中,赢得了无数的荣誉和粉丝的喜爱,但也同样招致了不少批评和厌恶。这种现象并非单一原因所致,而是由多个方面交织而成,可以从以下几个维度进行详细阐述:1. 个人性格与场上表现的争议: 过度自信和傲慢感.............
  • 回答
    喊麦这玩意儿,有人爱得不行,有人见了就绕道走,甚至可以说是深恶痛绝。这可不是因为什么高深莫测的艺术理论,而是掺杂了太多生活里的实在感受和价值判断。说到底,讨厌喊麦的人,他们觉得这东西“土”、“闹”、“没内涵”,甚至“低俗”。咱们就掰开了揉碎了聊聊,看看这背后到底是个啥逻辑。首先,得承认喊麦这东西,尤.............
  • 回答
    关于“腐女”这个群体为什么会有人讨厌,这个问题其实挺复杂的,涉及到社会观念、个人喜好、刻板印象以及网络文化等多个层面。你想了解得详细一些,那我这就给你掰开了揉碎了聊聊。首先,咱们得明确一下,“腐女”这个词本身是怎么来的。它源自日语的“腐女子”(ふじょし),最早是指对男性之间的恋爱关系(也就是同性恋情.............
  • 回答
    “我喜欢赵敏,你凭什么讨厌她?”很多人听到这句话,心中会泛起一丝不服气。的确,赵敏是金庸笔下最令人着迷的女性角色之一,她聪慧、果敢、敢爱敢恨,是多少人心中的白月光。但正如世上没有完美的人,赵敏也并非能够赢得所有人喜爱的类型。那些讨厌她的人,往往不是因为她恶毒狠辣,而是因为她身上某些特质,触碰到了他们.............
  • 回答
    看待清朝,如同看待一个复杂而庞大的家族历史,每个人从中读取到的故事和情感都可能截然不同。有的人对它深恶痛绝,有的人却又觉得它带着几分怀旧与亲切,这并非简单的立场对立,而是源于我们每个人所处的时代背景、个体经历以及我们关注历史的侧重点不同。讨厌清朝的理由,往往与屈辱、落后和压迫联系在一起。首先,民族主.............
  • 回答
    有些人会对弘扬主旋律感到反感,这背后其实涉及到挺多挺复杂的因素,不是一两句话能说得清的。我试着从几个方面来拆解一下,看看为什么会这样:1. 对“主旋律”的认知和理解差异:首先,得明白“主旋律”这个词本身就挺有解释空间的。在很多语境下,它指的是一种强调积极向上、团结一致、歌颂国家和集体价值的宣传模式。.............
  • 回答
    “五毛”这个词,在中文互联网上,就像是一颗投入平静湖面的石子,激起的涟漪常常是复杂的,甚至是带着些许厌恶的。为什么会有这么多人对“五毛”这个群体持有负面观感呢?这背后其实牵扯到很多层面的原因,我们可以从几个角度来细致地聊聊。首先,最直接的原因,也是最被大众诟病的一点,就是“收钱办事”的动机不纯。 “.............
  • 回答
    郑爽的演艺生涯,从最初的清纯邻家女孩形象深入人心,到后来的话题女王,她的经历确实充满了起伏和争议。很多人对她的看法,与其说是一种简单的“讨厌”,不如说是对她一系列行为和选择的复杂反应。下面我尽量详细地梳理一下,为什么她会招致如此多的负面评价,力求不带 AI 的痕迹,而是从普通人的视角去理解。首先,“.............
  • 回答
    好的,我们来详细探讨一下为什么现在有些人会讨厌中医。需要强调的是,这是一种复杂且多层次的现象,背后有多种因素交织在一起。以下是一些主要的观点和原因,我们将逐一展开:1. 科学证据不足与临床疗效的争议:这是最核心也是最普遍的批评点。 缺乏高质量的随机对照试验(RCT): 现代医学的黄金标准是RCT.............
  • 回答
    虽然美国队长是漫威电影宇宙(MCU)中最受欢迎的角色之一,受到许多观众的喜爱,但仍然有一些原因会让一些人讨厌他。这种讨厌并非普遍存在,而是源于对角色不同层面的理解、价值观的冲突、剧情的偏好,以及对超级英雄类型本身的一些看法。下面我将尽量详细地阐述这些原因:1. 他的道德观和行为准则过于完美和刻板: .............
  • 回答
    要说为什么胡歌身上好像有种自带“滤镜”效应,让大多数人对他好感多过厌恶,这事儿确实得掰开了揉碎了聊。毕竟,能在娱乐圈这个大染缸里保持多年路人缘这么稳固,还挺不容易的。首先,咱得从他的“作品实力派”标签说起。胡歌这人,演戏是真的没话说。从当年那个青涩的李逍遥,到《仙剑奇侠传》系列的经典,他演活了一个又.............
  • 回答
    说实话,小米这家公司,在中国乃至全球科技圈里,算得上是“话题制造者”了。它火的时候,粉丝们那叫一个热情似火,但讨厌它、甚至抵制它的人,那也不是不存在,而且往往理由还挺鲜明。这背后,其实是一系列复杂的原因交织在一起的。我先从最直观的,也是最常被拿来说事儿的“性价比”这个标签说起。1. “性价比”光环下.............
  • 回答
    关于《龙族》的讨论,就像一场永无止境的辩论,总有人在赞美它的宏大叙事和深邃设定,也总有人在它的字里行间挑剔出种种不适。要说讨厌《龙族》的人,其实原因五花八门,但如果非要细掰扯一下,大抵可以从几个方面说起。首先,最直接也最常见的,就是文笔和节奏的问题。这并非是说江南的文笔差到不能看,而是很多读者觉得他.............
  • 回答
    “爱狗人士”这个标签,听起来似乎天经地义,谁能讨厌爱护动物的人呢?但现实往往更复杂,当这份“爱”过度、偏激,甚至侵犯到他人权益时,它就可能变成一种令人反感的源头。现在有些人对所谓的“爱狗人士”感到不满,这种情绪的产生是多方面因素交织的结果,而且往往不是针对所有爱狗的个体,而是针对那些行为模式被普遍认.............

本站所有内容均为互联网搜索引擎提供的公开搜索信息,本站不存储任何数据与内容,任何内容与数据均与本站无关,如有需要请联系相关搜索引擎包括但不限于百度google,bing,sogou

© 2025 tinynews.org All Rights Reserved. 百科问答小站 版权所有