百科问答小站 logo
百科问答小站 font logo



为什么说指针是 C 语言的精髓? 第1页

  

user avatar   feng-dong 网友的相关建议: 
      

在开发中,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 都烧掉。


user avatar   feibingxw 网友的相关建议: 
      

指针的存在可以让程序直接操纵内存

这在很多没有指针的程序设计语言中是做不到的

因为可以直接操作内存,就有两点优势

1、更灵活

2、更高效


user avatar   flily 网友的相关建议: 
      

之所以说指针是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 ",
header->src[0], header->src[1], header->src[2],
header->src[3], header->src[4], header->src[5] );

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


user avatar   fan-ke-14 网友的相关建议: 
      

关键在于参数的传递吧。

因为,我们知道,c语言在参数传递的时候,只有一种,那就是值传递类型。


比如从函数A中跳到函数B中。我们调用函数B肯定是想为A服务的,但是现在跳到函数B中后,就是换了另外一个环境,所有的东西都是新的,它在栈上面重新分配了一块新的内存供函数B使用。所以从A传到B的变量只是在B中的栈中复制了一份,等到B调用完后,B中的所有东西,就没有了,销毁了,被OS回收了。所以A是找不到的。


再来看,如果你想要B来该表A中的变量a,那么你只是把A中变量的值a传入B的话,你是白做的了,因为B中的a和A中的a知识值一样而已,它们是完完全全的两个变量啊,你对B中的a做了如何改变,丝毫不会影响A中的a的值。


那么问题来了,怎么办?答案就是传递A中a的地址过去,因为A中a的地址是不变的啊,你在B中使用这个地址,依然是A中a的地址。所以,你传递&a过去,那么在B中操作这个地址,你就达到了改变A中a的值的目的。



理解上面的过程,你必须对函数的调用过程很熟悉,包括函数栈,内存回收的知识,以及一个进程的内存分布情况。




上面的传递过程还有一个优点:那么就是,如果变量a特别大,你只需要在B中复制一个地址值就可以了,这个代价是很小的。而且,如果你不想在B中改变a的值,你可以在传递的时候加上const关键字,任君选择。



总之,指针是很灵活的用法,它的可用性在于在内存中每个存储单元的地址都是唯一的。




  

相关话题

  大项目不允许使用C++STL 容器合理吗? 
  为什么有些编程语言写完一句后要加分号? 
  C标准库的行业地位是怎么形成的? 
  java的引用明明和指针没什么本质区别,java为什么还宣称没有指针并把这个当作语言的优点? 
  C 语言中不同类型指针的大小是否完全相同,为什么? 
  如何滴水不漏的学完C语言? 
  python是用C实现的,Java是用C++实现的,那为什么不直接用C或C++呢? 
  C++中 union 储存的 char 成员能否通过 int 成员读取? 
  为什么 C++ 的开源库看起来那么头大? 
  C++中如何将string类型转换为int类型? 

前一个讨论
从北洋时期到国民政府时期,究竟是历史的进步还是倒退?
下一个讨论
为什么西方女人不坐月子,中国女人必须坐月子?





© 2024-05-16 - tinynew.org. All Rights Reserved.
© 2024-05-16 - tinynew.org. 保留所有权利