user-0 提问: 请教 int* p 和 int *p 有什么区别吗? 谢谢

回复:
user: user-1
content: 这两个是一样的。

user: user-2
content: 单独的*一般是作为乘号才这样写，作为指针大多数还是与右边的符号结合，你去看大公司的源码就知道了，通常都这么写（比如Windows SDK的头文件中三种写法都有，以右结合居多）。

user: user-3
content: 引用 48 楼 linfaimom 的回复:[quote=引用 7 楼 sholber 的回复:] 什么缺陷不缺陷的，计算机最大的缺陷就是还需要人来编程。 话说朕从来不写int* p，也不写int *p，只写 int * p; 我也是这样，比较有强迫症[/quote] 其实这是最好的方案。int* p肯定是不合理的，但int *p也不科学。从类型派生的角度来看，指针类型派生自它所指向的类型，从声明的语法形式上来看，*应该独立存在才对。

user: user-4
content: 计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……

user: user-5
content: 引用 7 楼 sholber 的回复:什么缺陷不缺陷的，计算机最大的缺陷就是还需要人来编程。 话说朕从来不写int* p，也不写int *p，只写 int * p; 我也是这样，比较有强迫症

user: user-2
content: 引用 43 楼 SXJIAKE 的回复:[quote=引用 4 楼 DelphiGuy 的回复:] [quote=引用 2 楼 zhao4zhong1 的回复:] 虽然 int* p 和 int *p 没区别 但 int* a,b 和 int *a,*b区别就大了。  这就是C这类语言的设计缺陷之一，声明的书写是从左向右的，声明的解析却要从右向左，违反人的阅读习惯，而且也不利于编译。 [/quote]没觉得，我一直觉得 * 和变量是一个整体：int *a; 和 int *a, *b; 从右到左应该是你非要把 int * 作为一个整体来理解吧。[/quote]  不管是int* p; int *p; int * p; int*p;这个不存在谁和谁是一个整体的问题，只是书写形式，这个声明的解析就是从右到左的，你不会连这都理解不了吧。敢问哪个学校毕业的，青鸟还是蓝翔啊？

user: user-6
content: 引用 4 楼 DelphiGuy 的回复:[quote=引用 2 楼 zhao4zhong1 的回复:] 虽然 int* p 和 int *p 没区别 但 int* a,b 和 int *a,*b区别就大了。  这就是C这类语言的设计缺陷之一，声明的书写是从左向右的，声明的解析却要从右向左，违反人的阅读习惯，而且也不利于编译。 [/quote]没觉得，我一直觉得 * 和变量是一个整体：int *a; 和 int *a, *b; 从右到左应该是你非要把 int * 作为一个整体来理解吧。

user: user-2
content: 我没有谈您说的那些，我前面谈的是C（也包括C++）的变量定义/声明需要从右向左解析，这是它的一个设计上的缺陷，导致编译器设计上不能实现LR(k)解析器（这里k是一个常量），而只能做到LR(n)解析器（n是不确定的，解析时需要回看的tokens数量是不确定的），这是导致编译速度慢的一个重要原因。您如果理解不了的话需要先去补一下编译原理（估计青鸟蓝翔是不教这门课的，开个玩笑，不要介意）。

user: user-6
content: 引用 44 楼 DelphiGuy 的回复:[quote=引用 43 楼 SXJIAKE 的回复:] [quote=引用 4 楼 DelphiGuy 的回复:] [quote=引用 2 楼 zhao4zhong1 的回复:] 虽然 int* p 和 int *p 没区别 但 int* a,b 和 int *a,*b区别就大了。  这就是C这类语言的设计缺陷之一，声明的书写是从左向右的，声明的解析却要从右向左，违反人的阅读习惯，而且也不利于编译。 [/quote]没觉得，我一直觉得 * 和变量是一个整体：int *a; 和 int *a, *b; 从右到左应该是你非要把 int * 作为一个整体来理解吧。[/quote]  不管是int* p; int *p; int * p; int*p;这个不存在谁和谁是一个整体的问题，只是书写形式，这个声明的解析就是从右到左的，你不会连这都理解不了吧。敢问哪个学校毕业的，青鸟还是蓝翔啊？ [/quote]和你意见不同的就都是青鸟蓝翔毕业生了？我真不觉得 int * 算个类型，一直按 *p 是 int 类型来理解。当然，有人会拿 C 标准文档来反驳，不过各有各的道理，能说得通就是对的。我要是青鸟或蓝翔毕业的，你也是个校友。

user: user-7
content: 没什么区别啊 ， 你试试不就明白了？

user: user-8
content: 引用 38 楼 startstop2015 的回复:[quote=引用 33 楼 lm_whales 的回复:] [quote=引用 32 楼 startstop2015 的回复:] [quote=引用 12 楼 lm_whales 的回复:] typedef int (*array_ptr)[100] 是啥意思啊？ [/quote] 这是定义数组指针 你可以这样理解 int (*array_ptr)[100] ， (*array_ptr)是个int [100]（长度为100的int数组）； 所以 array_ptr 就是指向 int [100] 的指针了 就是 指向 100个元素的整型数组的指针. [/quote] 谢谢，我懂了，(*array_ptr) 这里的圆括号应该就是类型指派[/quote]差不多了  圆括号是优先级运算符,用来提升 *的优先级的， 没有圆括号 []优先级更高，所以array_ptr)先和[] 结合。 是的 (*array_ptr) 作为一个整体看待 int (*array_ptr)[100] 没有圆括号就是指针数组了 int (*fun_ptr)()没有圆括号 就是返回指针的函数了，有了圆括号 就是函数指针了  这里忘了说了 typedef 给一个类型 定义一个名字。 以后这个名字，就可以代表这个类型了。  typedef int (*array_ptr)[100]  就是定义 array_ptr为指针数组类型 typedef 就是 用定义变量的方式定义 类型 没有 typedef 。int (*array_ptr)[100]  定义了一个数组指针变量  . 有了这个  typedef array_ptr就变成类型了，数组指针类型。  可以用这个类型定义变量。 这对于复杂类型非常方便。

user: user-9
content: 没区别啊， 这是一个在前，一个在后

user: user-0
content: 引用 33 楼 lm_whales 的回复:[quote=引用 32 楼 startstop2015 的回复:] [quote=引用 12 楼 lm_whales 的回复:] typedef int (*array_ptr)[100] 是啥意思啊？ [/quote] 这是定义数组指针 你可以这样理解 int (*array_ptr)[100] ， (*array_ptr)是个int [100]（长度为100的int数组）； 所以 array_ptr 就是指向 int [100] 的指针了 就是 指向 100个元素的整型数组的指针. [/quote] 谢谢，我懂了，(*array_ptr) 这里的圆括号应该就是类型指派

user: user-10
content: http://lvvbbe.com/questions/3388496/declaring-pointers-asterisk-on-the-left-or-right-of-the-space-between-the-type-a

user: user-0
content: 引用 12 楼 lm_whales 的回复:这种区别是理念的区别， 对于C,C++来说， 只是语法分析时候， 读到读不到空格，以及空格的位置的区别  int *p; //强调 *p 是个int 类型。 int* p; //强调 p 是个 int* 类型。 int * p;//不偏不倚，无强调 int*p;  //不偏不倚,未免太挤。看着不是很舒服。 这四种写法，对于编译器，对于C语言，没有区别。 typedef int (*array_ptr)[100] 是啥意思啊？

user: user-11
content: 引用 36 楼 lm_whales 的回复:二者的区别， 1）数组指针： 初始化  int （*array_ptr）[100] =&a; 赋值：  array_ptr=&a；  2）指针数组： 初始化 int * ptr_arr[100]=｛a+0,a+1...a+100｝; 初始化         赋值：     for(int i=0;i<100;i++)                ptr_arr[i] =a+i; 3）函数指针： int (*fun_ptr)()， 有int fun1()，我记得可以fun_ptr=fun1 ; 和fun_ptr=&fun1都可以， 对的 前者数原来就有，后者是新的标准 函数代表一个代码单元 和数据本来就不同  函数名 就是地址 这是早期C 的概念 新的概念是 函数是个对象，  名字 代表这个对象，他有个地址 ， 名字在表达式中可以看作地址（函数指针），这是对老的概念的兼容  同时这个对象，也可以通过 & 获取地址，这是新的方法和概念。 学习了

user: user-12
content: 很早的时候，没有指针这个类型的，汇编里面只有地址这个类型，所以定义的时候，使用 *p 来定义一个地址变量。

user: user-13
content: 这个没有区别吧

user: user-8
content: 二者的区别， 1）数组指针： 初始化  int （*array_ptr）[100] =&a; 赋值：  array_ptr=&a；  2）指针数组： 初始化 int * ptr_arr[100]=｛a+0,a+1...a+100｝; 初始化         赋值：     for(int i=0;i<100;i++)                ptr_arr[i] =a+i; 3）函数指针： int (*fun_ptr)()， 有int fun1()，我记得可以fun_ptr=fun1 ; 和fun_ptr=&fun1都可以， 对的 前者数原来就有，后者是新的标准 函数代表一个代码单元 和数据本来就不同  函数名 就是地址 这是早期C 的概念 新的概念是 函数是个对象，  名字 代表这个对象，他有个地址 ， 名字在表达式中可以看作地址（函数指针），这是对老的概念的兼容  同时这个对象，也可以通过 & 获取地址，这是新的方法和概念。

user: user-11
content: 引用 34 楼 lm_whales 的回复:定义数组指针： int (*array_ptr)[100] :   //(*array_ptr) 是个数组 所以 array_ptr是个指向数组的指针  和 int * ptr_arr[100]:  // ptr_arr是个数组。这个数组有100个元素，每个元素都是 int * ;（单一的* 不单独解释）  所以这是个指针数组。 如果有一个int a[100]，那么可以array_ptr=a还是array_ptr=&a呢？ 如果是函数指针int (*fun_ptr)()，有int fun1()，我记得可以fun_ptr=fun1？ 很少用这些，语法都不太熟，书上讲得也不详细。