C++指针的*号位置为什么这么别扭啊

2020-10-15 17:09:47 +08:00
 zxCoder
int *fun(){}

这是返回一个 int 型指针,咋不写成

int* fun(){}

我的理解是为了强调 int*不是一个类型,而*函数名()就表示返回一个“所声明的返回类型”的指针类型。

Clion 自动格式化也会格式化成第一种

2746 次点击
所在节点    问与答
26 条回复
BrettD
2020-10-15 19:15:27 +08:00
因为 int* a, b;的意思是 int *a, b
geelaw
2020-10-15 19:18:20 +08:00
int * 当然是类型。正确的原因如 #1,因为 * 是和标识符结合,而不是和类型名字结合。

int *a, b; 的意思是 int *a; int b; 如果写成 int* a, b; 则容易误以为意思是 int *a; int *b; 所以 * 永远靠近标识符。为了一致性,在声明返回类型的时候也让 * 靠近标识符(即函数的名字)。
kokutou
2020-10-15 19:18:43 +08:00
复制粘贴的:

以下文字摘自<高质量 C++编程指南>:

修饰符 * 和 & 应该靠近数据类型还是该靠近变量名,是个有争议的活题。

若将修饰符 * 靠近数据类型,例如:int* x; 从语义上讲此写法比较直观,即 x 是 int 类型的指针。

上述写法的弊端是容易引起误解,例如:int* x, y; 此处 y 容易被误解为指针变量。虽然将 x 和 y 分行定义可以避免误解,但并不是人人都愿意这样做。
letking
2020-10-15 19:27:35 +08:00
不管怎么解释,这种写法确实别扭。
zxCoder
2020-10-15 19:43:01 +08:00
@kokutou 我感觉就是设计问题,但是已经太难改了,类似于 int* x,y 在很多语言应该都是表示两个 int* 变量,而 c++非要表示一个 int*,一个 int,然后说引起误解。。。。
当然也可能是我先学了其他语言,先入为主
zxCoder
2020-10-15 19:44:07 +08:00
@BrettD
@geelaw
你们觉得这是最初的设计问题吗?我觉得在大多数现代语言中,类似于 int* x,y 的表达应该都是表示两个 int*类型的,感觉更容易理解。
zxCoder
2020-10-15 19:45:04 +08:00
@letking 写习惯了应该还好,像我这种半吊子就容易看错代码,理解半天哈哈哈
AlohaV2
2020-10-15 19:45:47 +08:00
我一般就写 T* SomeWhatFunction()
参考 https://google.github.io/styleguide/cppguide.html#Pointer_and_Reference_Expressions
我觉得是保持整个项目的风格一致即可,没那么多条条框框
secondwtq
2020-10-15 19:47:23 +08:00
这不是 C 的问题么 ... 我 C++ 虽然垃圾,但是也要面子的啊
嘛,C++ 加了一个引用 ... 在这方面很相似

我觉得这样设计一个可能的动机是保持标识符的定义与使用一致,也就是说定义的时候用 *a,使用的时候也用 *a,*a 这个表达式的类型就是 int 。
Mutoo
2020-10-15 19:51:49 +08:00
https://clang.llvm.org/docs/ClangFormatStyleOptions.html

# Force pointers to the type for C++.
DerivePointerAlignment: false
PointerAlignment: Left
dandycheung
2020-10-15 19:52:22 +08:00
@zxCoder 跟设计关系不大,保证自己不用指针类型同时定义多个变量的前提下,我每次都会把星号挨住类型,别人的代码的话,我也要强制改过来,除非是独立的源文件,不需要大动的。
secondwtq
2020-10-15 19:58:51 +08:00
@zxCoder #6 C 不是“现代语言”,C++ 想要“现代”也“现代”不起来了。
其实现在 C++ 和 Rust 这种零开销抽象语言里面一堆智能指针,感觉已经没啥必要给指针专门设计语法了。
rrfeng
2020-10-15 20:10:40 +08:00
一个声明语句里同时声明两个不同类型的变量,其他语言没有这么写的。就是设计的别扭而已……
elfive
2020-10-15 20:12:37 +08:00
因为#1 和#2 的原因,所以我总是在*两边加上一个空格,这样就写成了:
int * a, b;
int * foo(){ return bar; }

这样比较居中的话我个人觉得没有侧重,多数情况下都还算好理解。
lxk11153
2020-10-15 20:27:09 +08:00
哈哈,联想到 Java
String[] a={};
String b[]={};
// ----
String[] c={}, d={};
// ----
String e[]={}, f[]={}, g="";
blless
2020-10-15 20:29:47 +08:00
虽然一开始觉得 go 别扭 不过感觉 go 就没有这方面困扰 反正类型都后置
Akiyu
2020-10-15 20:35:04 +08:00
int *a;
除了楼上所说的以外. 从类型对称上来说 int 和 *a 分开. 左右对称. 意为 *a 是 int 类型. 而 a 只是个指针.
从这方面来说. 也可以辨别 * 应处的位置.
kokutou
2020-10-15 20:45:27 +08:00
@zxCoder #5
c++要兼容 c
c 是多久以前发明的...

这包袱甩不掉
sillydaddy
2020-10-15 21:14:37 +08:00
@Akiyu 同意
楼主可以从 17 楼的解释来理解。
int *foo()的意思是*foo()的类型是 int,这样 foo 函数返回类型自然就是一个指向 int 的指针,用*对指针取值才得到 int 类型。
sillydaddy
2020-10-15 21:20:19 +08:00
@sillydaddy 也就是说,你既可以把*看作是指针的符号,同时也可以看作是对指针取值的操作符。
这样的话,int *a 的含义,可以理解为 a 是 int *,也可以理解为,对 a 这个变量用*取值后,得到的值类型为 int,那 a 自然就是 int 类型的指针啊,因为只有对 int 型的指针取值,得到的才是 int 型的值啊。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/715311

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX