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



为什么C语言用int *a 来声明指针变量,而不是int &a声明? 第1页

  

user avatar   huang-jing-cheng 网友的相关建议: 
      

C 语言发明的时间很早,当时人们对"类型系统" 还很陌生,很多人还习惯将二进制字节作为唯一的数据类型。设计 C 语言的语法时,也不知是谁想出来的,有种设计哲学:让声明的形式与它的使用形式尽可能相似。在这种设计哲学下,是先想如何使用,再来逆推如何声明,这样 C 语言的声明语法显得有点古怪,


比如:

  • 声明 int a; 使用时,a 的类型就是 int。
  • 声明指针 int *b; 使用时,*b 的类型就是 int。
  • 声明数组 int b[10]; 使用时用 b[0];
  • 定义函数指针,int (*ptr)(int a, int b); 使用时,就是 (*ptr)(a, b); 可以简写成 ptr(a, b);

C 这种语法设计,在今天看来是不好。使用这种语法,程序员不可以直接从左往右读,有时甚至需要从中间往两边读。只是 C 语言的影响太大,人们常见类 C 的语法,C 语言有些不好的地方也就忍了。C++ 就继承了这种语法,甚至这种语法的设计哲学,反正我总记不住成员函数指针是怎么声明的。


到今天,人们对“类型系统" 很熟悉了,也积累了几十年的语言使用经验。现在设计的语言,语法上倾向将类型放到后面,而并非放到前面。这样比较统一,也可以从左往右读。比如

       var a : Int; var b : [Int]; var ptr : (Int, Int) -> Int; var signal : (Int, Int -> Void) -> (Int -> Void);      

对比 C 语法

       int a; int b[10]; int (*ptr)(int, int); void (*signal(int, void(*)(int)))(int);      

特别最后一个类型,没有什么人可以一眼可以看出它的含义(我怀疑已经写错了)。这种情况,在 C 中会用 typedef 来简化。

       typedef void (*handler_t)(int); handler_t signal(int, handler_t);      

想了解更多,请阅读 C 专家编程 第 3 章。


-----------------

简单讨论前置类型(类型放在变量前面)和后置类型(类型放在变量后面)。跟原题目无关,是对评论的回复。这只是个人看法。


语言有类型推导,很多时候不用显式写类型。类型放在前面或者后面,对基本的数据类型影响还不算大。只是对复合类型,特别是函数(或者类似概念),语法上还是有影响的。怎么从语法上表示一个函数呢?使用前置类型,从语法上,大致可以写成:


       Func<int(int, int)> fun;      

你也可以去掉括号,写成,


       Func<int, int, int> fun;      

规定前面是参数类型,最后的是返回类型。但这种方式,从形式上是看不出那些是返回值,那些是参数。


你很难去掉这个 Func 的记号,去掉会引起歧义。更进一步,怎么去表示一个函数,它传入一个函数作为参数,而返回一个函数呢?大致为:

       Func<Func<int, Void>, Func<int, Void>> fun;      

这种语法,就会引起 Func 的嵌套,而 Func 纯粹多余。

更进一步,我增强了语言,可以支持多返回值。按照 C 的语法方式,大致定义成:

       (int, int) fun(int a, int b);      

那怎么表示这种函数类型呢。你可以写成:

       Func<(int, int), (int, int)> fun;      

那再继续,怎么表示这种,定义一个函数,传入一个多返回值的函数作为参数,而再次返回一个多返回值的函数作为参数。这样,不单单是 Func 会引起嵌套,连那些括号也会引起嵌套,而这些是语法噪音。为避免嵌套,语言中就会倾向于先定义某个类型,比如

       typedef Func<int, Void> FuncT; Func<FuncT, FuncT> fun;      

类型写在后面,可以轻易地去掉 Func 噪音。比如

       var fun: (int -> void) -> (int -> void)      

并且它的形式并非是嵌套的,而是一个线状,并且可以统一地连锁下去。


另外还有更具价值观的解释,编程时更应该关注变量用途,而不是变量的类型。变量的名字反应了用途,既然用途比类型更重要,名字就应该放在最开始。当然这种解释见仁见智,有点站不住脚。


user avatar   pansz 网友的相关建议: 
      

开局一张图,剩下全靠猜?这个没法评价。

从软件的角度虽然我能想出两三种导致这个现象的原因,但非正式发布的产品出现任何问题都是常见现象。盲人摸象的评价没有必要。

跟11代没差别,这个肯定是违背常识的,要知道11代i9只有16线程,12代i9有24线程,24线程超越16线程并不需要多么高超的优化技巧。

调度优化的主要难题是当我们只需要少量线程运作的时候究竟把这个线程安排在哪个核心。

然而,对于全核心全线程同时计算的场景来说,反正都是全核心上场,根本不需要什么优化,谁来都是全核心工作。

如果这个软件能把所有核心用满的话,没道理性能不变。所以肯定有某个环节出了问题。正式版本再说吧。




  

相关话题

  知乎用户 @萧井陌 写代码什么水平? 
  为什么C没有布尔类型? 
  JSON「最后不能加逗号」是不是错误设计? 
  为什么现在有很多人,甚至大学授课还在坚持 VC 6? 
  现在的可视化编程发展到什么程度了,什么时候可以取代高级语言? 
  C++ 有多难? 
  深度学习底层开发对数学有哪些要求? 
  学生党可不可以电脑只装 Linux 操作系统? 
  为什么 Linux 指针越界时程序会立即被中断,而 Windows 不会? 
  该如何正确看待c中的字符串常量? 

前一个讨论
现在 ( 2016 年 8 月),Surface Pro 4 的实际体验如何?
下一个讨论
《西游记》里的孙悟空和唐僧性格颠倒一下会怎样?





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