迷你书下载 精彩片段: 恶名昭著的指针究竟是什么:报错 -问答-阿里云开发者社区-阿里云

开发者社区> 问答> 正文

迷你书下载 精彩片段: 恶名昭著的指针究竟是什么:报错

kun坤 2020-06-09 15:10:04 54

指针——C语言的灵魂 为什么说C指针是C语言的灵魂? 买前必读: 迷你书下载 精彩片段: 恶名昭著的指针究竟是什么:报错

为什么说C指针是C语言的灵魂?

来自读者对C和指针的解说
  1. 他可以直接访问硬件,这是灵活性和效率的体现,程序离硬件越近自然效率越高,当然运用不当也可导致效率低下
  2. 难掌握及太危险,如果对指针理解含混,访问过程不当易导致程序奔溃或隐藏潜在危险
  3. 指针作用总的说是调高程序运行效率,原因是它对c语言中定义的各种数据结构进行地址传递,而不需要进行不断地进行值传递。理解起来可以联想一下数据共享与建立副本的区别。
注:欢迎各位程序猿们继续补充 挖掘C语言的灵魂,先看《征服C指针》这本书 enter image description here 读者对本书的评价:
  • 针对性极强,全书以一种精准但又不考究的方式解读C语言指针。看过经典的“C和指针”后再看看日本程序员对指针的理解,也许会获得又一番的感悟。这是最棒的C书 、
  • 日本人都是工匠,从精密机械到各种探测器,从av情色片到美食,小日本干任何事都精益求精。 我看过小日本的几本计算机书,binary hack, debug hack, 以及这本,全都是精品。 他们的书逻辑性不强,特点是人的因素多,注重细节,教给读者诀窍,读来畅快淋漓,爱不释手。 可能我的性格里也有黑客的成份吧,不喜欢那种冷冰冰的知识罗列的书

买前必读:

这是一本关于C 语言的数组和指针的书。 ■ 本书的读者群虽然定位于“学习过C 语言,但是在指针的运用上遇到困难”的读者,但还是能随处可见一些高难度的内容。那是因为我也不能免俗,偶尔也喜欢把自己掌握的知识拿出来显摆一下。 ■ 对于初学者,你完全没有必要从头开始阅读。遇到还不太明白的地方,也不要过分纠结。阅读中可以跳跃章节。对于第0章和第1章,最好还是按顺序阅读。如果认为第2章有点难度,你可以先去啃第3章。如果第3章也不懂,不妨尝试先去阅读第4章。这种阅读方式是本书最大的卖点。 ■ 在本书中,我会经常指出一些“C的问题点”和“C的不足”。可能会有一些读者认为我比较讨厌C语言。恰恰相反,我认为C是一门伟大的开发语言。倒不是因为有“情人眼里出西施”、“能干的坏小子也可爱”这样的理由,毕竟在开发现场那些常年被使用的语言中,C语言还是有相当实力的。就算是长得不太帅,但论才干,那也是“开发现场的老油条”了。

迷你书下载

精彩片段:

应该记住:数组和指针是不同的事物

为什么会引起混乱? 首先,请允许我强调一下本章的重要观点。 C 语言的数组和指针是完全不同的。 大家都说C语言的指针比较难,可是真正地让初学者“挠墙”的,并不是指针自身的使用,而是“混淆了数组和指针”。此外,很多“坑爹”的入门书对指针和数组的讲解也是极其混乱。 比如,K&R 中就有下面一段文字(p.119), C 语言的指针和数组之间有很强的关联关系,因此必须将指针和数组放在一起讨论。 很多C程序员认为“数组和指针是几乎相同的事物”,这种认识是引起C的混乱的主要原因。 从图3-17中可以一目了然地看出,数组是一些对象排列后形成的,指针则表示指向某处。它们是完全不同的。 enter image description here 带着“数组和指针是几乎相同的事物”这样的误解,初学者经常写出下面这样的代码:
int *p; p[3] = …… ←突然使用没有指向内存区域的指针 ——自动变量的指针在初期状态,值是不定的。 char str[10]; . . . str = abc”; ←突然向数组赋值
——数组既不是标量,也不是结构体,不能临时使用。 int p[]; ←使用空的[]声明本地变量 ——只有在“函数的形参的声明”中,数组的声明才可以被解读成指针。 对于数组和指针,它们在哪些地方是相似的,又在哪些地方是不同的?不好意思,可能在下面会出现和前面重复的内容。 表达式之中 在表达式中,数组可以被解读成指向其初始元素的指针。所以,可以写成下面这样:
int array[10]; p = array; ←将指向array[0]的指针赋予p
可是,反过来写成下面这样,
array = p;
就是不可以的。确实,在表达式中array 可以被解读成指针,可是,本质上它其实是被解释成了&array[0],此时的指针是一个右值*。(此时的指针是右值这个理由之外,在标准中,数组也不是“可变更的左值”。) 比如,对于int类型的变量a,a = 10;这样的赋值是可以的,但肯定没有人想做a + 1 = 10;这样的赋值吧。尽管a 和a + 1 都是int,但是a + 1没有对应的内存区域,只是一个右值,所以不能被赋值。同样的道理,array也不能被赋值。此外,对于下面这个指针,
int *p;
如果p指向了某个数组,自然可以通过p[i]的方式进行访问,但这并不代表p就是指针。 p[i]只不过是*(p + i)的语法糖,只要p正确地指向一个数组,就可以通过p[i]对数组的内容进行访问,如图3-18所示。 enter image description here 如果是“指针的数组”和“数组的数组”,就会有很大的不同。
char *color_name[] = { ←指针的数组 red”, green”, blue”, };
对以上的代码进行图解(参照图3-19),
![enter image description here][5] char color_name[][6] = { red”, green”, blue”, }
对以上的代码进行图解(参照图3-20), enter image description here 以上两种情况都可以用color_name[i][j]的方式对数组进行访问,但是内存中数据的布局是完全不同的。 声明 只有在声明函数的形参的时候,数组的声明才能解读成指针的声明(参照3.5.1节)。 以上的语法糖,与其说使C变得更加容易理解,倒不如说它使C语言的语法变得更加混乱。是不是有很多人这么想?我就是其中的一个(虽然使用这个语法糖可以让多维数组作为参数被传递时更容易理解……)。而且K&R的说明更是使这种混乱局面雪上加霜。 在不是声明函数的形参的时候,数组声明和指针的声明是不可能相等的。 使用extern 的时候是最容易出现问题的(参照3.5.2节)。另外,声明局部变量或者结构体的成员时,写成
int hoge[];
会引起语法错误(对于结构体的成员,在ISO C99 中是允许这种写法的)。 存在数组初始化表达式的情况下,可以使用空的[],但这是因为编译器能够计算出数组元素的个数,所以可以省略书写元素个数。仅此而已,这种特征和数组扯不上任何关系。 要 点 【非常重要!!】 •数组和指针是不同的事物。

恶名昭著的指针究竟是什么

关于“指针”一词,在K&R 中有下面这样的说明(第5 章“指针和数组”的开头部分): 指针是一种保存变量地址的变量,在C 中频繁地使用。 其实在表达上,这样的说明是有很大问题的。总会让人感觉,一旦提起指针,就要把它当作变量的意思。实际上并非总是如此。 此外,在C 语言标准中最初出现“指针”一词的部分,有这样一段话: 指针类型(pointer type)可由函数类型、对象类型或不完全的类型派生,派生指针类型的类型称为引用类型。指针类型描述一个对象,该类对象的值提供对该引用类型实体的引用。由引用类型T 派生的指针类型有时称为“(指向)T 的指针”。从引用类型构造指针类型的过程称为“指针类型的派生”。这些构造派生类型的方法可以递归地应用。 这段话的内容也许会让你一头雾水(既然是标准,那总要有点标准的范儿吧)。那就让我们先关注第一句话吧,那里出现了“指针类型”一词。 提到“类型”,立刻会让人想起“int 类型”、“double 类型”等。同样,在C 语言中也存在“指针类型”这样的类型。 “指针类型”其实不是单独存在的,它是由其他类型派生而成的。以上对标准内容的引用中也提到“由引用类型T 派生的指针类型有时称为‘(指向)T 的指针’”。 也就是说,实际上存在的类型是“指向int 的指针类型”、“指向double的指针类型”。 因为“指针类型”是类型,所以它和int类型、double类型一样,也存在“指针类型变量”和“指针类型的值”。糟糕的是,“指针类型”、“指针类型变量”和“指针类型的值”经常被简单地统称为“指针”,所以非常容易造成歧义,这一点需要提高警惕*。 (*至少本书还是尽力将这些说法进行区别的,但有时候,无论怎么写也做不到自然地表述想要表达的意思,最后只好投降……非常抱歉。) 要 点 先有“指针类型”。 有了“指针类型”,才有了“指针类型的变量”和“指针类型的值”。 比如,在C中,使用int 类型表示整数。因为int是“类型”,所以存在用于保存int型的变量,当然也存在int型的值。指针类型同样如此,既存在指针类型的变量,也存在指针类型的值。 因此,几乎所有的处理程序中,所谓的“指针类型的值”,实际是指内存的地址。 变量的内容是保存在内存的某个地方的,“某个地方”的说法总是会让人产生困惑,因此,就像使用“门牌号”确定“住址”一样,在内存中,我们也给变量分配“门牌号”。在C的内存世界里,“门牌号”被称为“地址”。

相关阅读:

分享到
取消 提交回答
全部回答(1)
  • kun坤
    2020-06-09 19:20:10

    以下文字摘自《C陷阱与缺陷》,写的非常好,很有必要摘录下来和大家一同分享。

          C语言中的数组值得注意的地方有以下两点:

          1.C语言中只有一维数组,而且数组的大小必须在编译期就作为一个常熟确定下来。然而,C语言中数组的元素可以是任何类型的对象,当然也可以是另外一个数组。这样,要“仿真”出一个多维数组就不是一件难事。

           2.对于一个数组,我们只能够做两件事:确定该数组的大小,以及获得指向该数组下标为0的元素的指针。其他有关数组的操作,哪怕它们乍看上去是以数组下标 进行运算的,实际上都是通过指针进行的。换句话说,任何一个数组下标运算都等同于一个对应的指针运算,因此我们完全可以依据指针行为定义数组下标的行为。 ######可不可以理解这是广告###### 难掌握的是计算机体系
    搞不懂指针的都是体系没学好的 ######国内好多数组和指针搞不清楚的教材害人呀。######明显广告######受益匪浅,对指针的看法有了更具体的认识,没那么抽象了。

    0 0
云计算
使用钉钉扫一扫加入圈子
+ 订阅

时时分享云计算技术内容,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。

推荐文章