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



为什么有人讨厌指针? 第1页

  

user avatar   zhan-qi-lai-74-48 网友的相关建议: 
      

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

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


这些教材喜欢故弄玄虚,说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; }     




  

相关话题

  你能否在不传递指针的情况下通过函数交换两个变量的值,如果可以请说明方法,如果不行请分析原因。?计算机? 
  如果一门编程语言中不允许对象(或结构体)循环引用,那么用它实现什么功能会比较困难? 
  为什么C/C++中“(*p).number”和“p->number”作用一样但却有两种写法? 
  为什么有人讨厌指针? 
  请问指针的这些概念如何理解? 
  指向指向指向指针的指针的指针的指针有什么用? 
  为什么有人讨厌指针? 
  为什么有人讨厌指针? 
  如何评价C语言让数组退化为指针的设计? 
  int *p=new int,当free(p)时free函数是怎么知道要释放4个字节而不是5个的? 

前一个讨论
如何看待各汽车厂商准备放弃内燃机?
下一个讨论
如何正确地区分“艺术”和“垃圾”?





© 2024-11-22 - tinynew.org. All Rights Reserved.
© 2024-11-22 - tinynew.org. 保留所有权利