非C系列的语言有没有指针,为何说指针是 C 语言的精髓?

简单来讲,由于C就那点破feature,若是你把指针干掉,那这语言就完了。相反,若是你干掉struct,干掉union,干javascript

掉数组,甚至你把if-while都干掉,留下malloc和goto,则最多就是程序难写一点而已。java

因此这就是为何C语言的精髓是指针了,由于他只有指针能够用了。node

把struct和数组都砍掉以后c++

只能用char*让后处处指针运算和强制转换了,由于没有了内存布局程序员

没if怎么goto算法

把两个continuation的函数指针装进数组里面,算出个true和false,用下标拿出来,当场代替if。还须要开开眼界。编程

没有数组c#

只要有malloc就成数组

干掉if 怎么判断goto能不能跳缓存

void (*Fuck[2])();

Fuck[1] = &TrueBranch;

Fuck[0] = &FalseBranch;

int condition=/*evaluate your condition*/;

Fuck[condition](/*some context variables*/);

之因此说指针是C语言的精髓,在于,你会用指针、用好指针以后,能发挥C语言的强大威力;若是你不会用,C语言

绝对不会比其余的任何一种语言好。 举两个我本身比较熟悉的例子。一个是函数指针,好比一个计算一元实函数定积分的函数,能够写成以下形式

double integrate( double (*f)( double x ), double lb, double ub );

其中,lb是积分下界,ub是积分上界,f是被积函数(的指针)。这样就能够对全部double (*)(double x)形式的函数进

行积分计算了。可是,若是是在Java中,实现这个功能可能就会比较麻烦。首先须要为这个计算积分的函数声明一个

积分计算器的类,而后声明一个可积分的接口,可以被积分的函数的类须要继承并实现这个接口,而后再把这个被积

函数的类的一个实例传给这个这个积分计算器进行计算....

另一个用得比较多的是结构体指针。若是只把结构体当成一个数据的集合的话,那么结构体并无什么好用的。在

处理二进制格式的数据,尤为是网络数据的数据包的时候,结构体指针很是好用。好比咱们定义一个以太网帧首部的

格式

struct eth_header {

unsigned char dst[6];

unsigned char src[6];

unsigned short int ptype;

};

咱们用socket读到一段二进制数据的时候,把指向该缓存的指针,用一个强制类型转换变成一个struct eth_header*类

型的指针,那么这个数据包的内容就能够很容易的读出来了。好比读源地址,只须要这样

unsigned char* buffer = .......

struct eth_header* header = (struct eth_header*) buffer;

printf( "SRC-MAC: %02X-%02X-%02X-%02X-%02X-%02X\n",

header->src[0], header->src[1], header->src[2],

header->src[3], header->src[4], header->src[5] );

这样的特性,在Java这些高级语言里面就比较难以作到。

C语言的指针,关键意思在于“指”。

“指”是什么意思?

其实彻底能够理解为指示的意思。好比,有一个物体,咱们称之为A。正是这个物体,有了这么个称谓,咱们才可以

进行脱离这个物体的实体而进行一系列的交流。将一个物体的指示,是对这个物体的抽象。有了这种抽象能力,才有

所谓的智慧和文明。因此这就是“指示”这种抽象方法的威力。

退化到C语言的指针,

指针是一段数据/指令(在冯诺易曼体系中,两者是相通,在同一空间中的)的指示。这是指示,也就是这段数据/指

令的起始位置。可是数据/代码是须要一个解释的方法的。好比0x0001,能够做为一个整数,也能够做为做为一串指

令,也能够做为一串字符,总之怎样解释均可以。 而C语言,在编译阶段,肯定了这段数据/指令的“解释方法”。

例如,整型指针,表示的就是能够从这个指针p指向的位置开始解释,解释为一个整数

。 一个函数指针,表示的就是能够从这个指针p指向的位置开始解释,解释为一段指令,对应的输入和输出以及返回值

按照函数指针的类型,符合相应的要求。 综上,C语言的精髓是指针,但指针不只仅是C语言的精髓,它是抽象的精髓。各个语言中都有相似的东西,例如函

数,例如引用。 (引用和指针的区别,个人理解,不能够进行+/-偏移操做的指针,就是引用。随意偏移,很容易使得目标位置不符合

其相应的意义,从而形成解释失败,进而崩溃。而增长了偏移功能的指针,好处是方便表述一堆具备相同类型的数据/

指令,数组之类的就是这样的实例。) 一样的void类型的指针,也是C语言的特点。void型的指针,就是去掉了指定类型的指针,从而使得能够以任意解释

方式,解释指针,这就带来了如上的潜在问题。可是也能够说,这个C语言的特有威力(我通常都把C语言的威力理

解为这个)。这个带来的好处很是之灵活。由于可使用统一的类型来表述全部类型的数据。带来的问题,和上面是

相似的。就是若是解释方法不当,就会形成灾难性的后果。C语言的强制类型转换也是打破常规的指针解释.也有可能

带来问题. 发现最后说偏了,但既然写上了,就放在这里吧。欢迎讨论。

澄清两点:

1.经过指针能实现所谓的“传引用”而不是“传值”,本质上节约了数据传输性能

2.光支持指针不是c出彩的地方,要支持指针的运算(对指针加减,甚至取指针)才是c类语言强大的地方。只支持传

引用的语言大把大把。 因此说前面不少回答的人都是只知其一;不知其二,彻底没有答到点子上。

在开发中,data structure 越复杂,算法就越简单。

据说过 XML 的 parser 分为 SAX 和 DOM 两种吧?其中 SAX 就是 event-driven,没有 data structure,因此很是

难用。

据说过 one-pass compiler 和 multi-pass compiler 吧?前者几乎不用生成语法树,但是实现超级晦涩。

有人问过 GPU 为何那么快?GPU 没有 data structure,要求数据高度对其,因此那么快。但是把 CPU 算法改

写成 GPGPU 超级难。

Data structure 依靠的就是指针。不能靠内存的绝对位置表示数据的关系吧,那样的数据移动操做能把 data bus 都烧

掉。

C 语言只有值的传递,没法直接传递引用,要想传递引用必须经过指针间接实现。 若是 C 语言没有指针,一切都经过值传递,参数将永远只有输入参数,全部的结构体只要参与运算都具备极高的开

销,由于每传递进函数参数一次就必须全体复制一次。 另一点:C语言没法在参数中传递数组,一切数组在函数参数传递时退化为指针,所以若是没有指针,数组将没法

经过函数参数传递。 还有一点,在C语言中函数是一个指针,若是没有指针,就没法定义C语言函数,没法使用和调用C语言函数,更没法

将函数做为一个变量传递。——换句话说,没有指针,C语言将没有函数,一个没有函数的语言会是什么概念? 实际上指针这概念在绝大多数高级语言中都广泛运用了,只是人家不叫指针,一般叫作引用而已。例如 Java 的全部

对象变量从 C 语言的角度都实际上保存的是一个指针而不是对象自己。 彻底的舍弃指针,C程序将变得低效难懂,由于你没法让在任何子函数中修改一个结构体的内容。这种程序相似于无

状态程序。 我不知道指针算不算所谓“精髓”,但能够确定的是没有指针的 C 语言几乎不可能进行任何有实际意义的正常的编程。

甚至没有办法完整的实现 C 语言标准库。指针对 C 语言来讲是必需品而非奢侈品。

说精髓有点过了,有点玄乎了。c,c++是面向一个flat内存模型为基础,指针系出自自然。你看到的c++代码几乎都是

和指针有关,几乎都是使用和操做指针。由于动态分配,传递数据结构,对象的参数几乎都是指针。

(1)汇编和指令级别就有指针概念,因此c,c++里有指针是很天然的事。

(2)配合内存管理,必须须要指针概念。

(3)例如,文件的区块性加载或存储,一整块数据结构。其余语言由于OO了,你可能一般要一个字段一个字段来。

(4)指向代码的指针:函数指针,是插件架构,不一样人编写不一样模块合做的基础。

(5)c、c++中特有的半开口的可扩展内存。

(6)指针和数组模型的自然无缝。 其余的就没什么了,好比说指针的转型,虚函数表,这些把指针概念掩盖起来,其余语言也有对等。好比分配对象

,释放对象,可以对程序员隐藏指针的概念。好比函数指针到了c#里成了委托,实际上仍是函数指针概念更加直接。

另外,一个指向某个地址的指针,和hold一个对象,两种概念之间,前者属于很是鲜明的面向内存模型的思惟方式。

这种思惟方式和OO有时候能够等价,但有时候又有区别,可能须要你本身多加体会把。好比说,c语言里的字符串操

做,基本上必须之前者做为思惟方式,在c++里的string,由于c++须要你掌握太多细节,因此你要彻底脱离前者的内

存模型也几乎不可能,脱离了你可能会犯错。

【补充】:

只有把内存管理权交给程序员,C++程序才能作到内存的使用如此灵活和自由,才能达到高效。C++程序的内存分配

策略能够是灵活而动态的,达到真正的按需分配,根据配置文件决定,这不是在编译期的傻傻的静态决定,而是运行

期决定。 须要负责内存管理的C++,天然也就是说,模型暴露的很底层,也就很天然也是形势必须的把指针概念传达到语言层

面,交给程序员来控制。

顺带解释几个精髓: asm: machine code is hard to r/w

c: asm is too trivial

c++: c doesn't have class

java: c++ has pointers

javascript: scheme doesn't like c

nodejs: c is too low-level for asyn programming

clojure: java is not lisp 本质上C是加了一层语法糖的汇编,引进当时先进的函数,保留了汇编强大的地址直接访问功能 —— 也就是所谓的指

针功能,以增长操做灵活性。

http://www.zhihu.com/question/20125963

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值