当c指针在c指针上时,很难理解它';s自身(第二部分)
当我看到实际的乘法运算时,我问了这个问题,每个人都帮助我清楚地理解它(所以我非常感激) 然而,在不同的情况下,这仍然困扰着我 比如,当c指针在c指针上时,很难理解它';s自身(第二部分),c,pointers,C,Pointers,当我看到实际的乘法运算时,我问了这个问题,每个人都帮助我清楚地理解它(所以我非常感激) 然而,在不同的情况下,这仍然困扰着我 比如, int main(int argc, const char * argv[] ) 为什么上面写的和下面不一样 int main(int argc, const char *argv[] ) 有区别吗?有时我会看到*的一些奇怪的位置,我只是不明白为什么它们有时似乎在它们喜欢的任何地方浮动(或者我猜是谁知道它们在做什么)。您显示的两行代码的含义完全相同。C通常忽
int main(int argc, const char * argv[] )
为什么上面写的和下面不一样
int main(int argc, const char *argv[] )
有区别吗?有时我会看到*的一些奇怪的位置,我只是不明白为什么它们有时似乎在它们喜欢的任何地方浮动(或者我猜是谁知道它们在做什么)。您显示的两行代码的含义完全相同。C通常忽略水平空白;它唯一起作用的是(1)字符串内的文字,(2)当它更改标记的边界时(考虑
++x
与++x
),(3)当它控制您是#定义类似函数还是类似对象的宏时
在类型声明的上下文中,*
不是二进制乘法运算符,它是指向修饰符的一元指针,并且它总是影响右边的事物。为清楚起见,编写时应始终在左侧留有空格,右侧不留空格,但编译器并不在意
在C++中,将星向左拥抱是错误的,因为它是误导的:<代码> char *a,b < /c>不声明为<代码> a <代码> >代码> b >代码>作为指针。首先在一行上声明变量,这本身就是一个合理的位置,但并不是误导人类读者有关*
绑定方向的有效借口。然而,这完全是风格问题,编译器也不在乎。)在这种情况下,空格并不重要。您可以将其写成
char *argv[]
或
或
甚至
char*argv[]
所有四种形式都被解析为char(*argv[])
;*
运算符是声明符的一部分(与[]
运算符一样)
在编译过程中,源代码被分解为标记;非正式地说,标记是程序中最小的有意义的部分(关键字、运算符、标识符、文字、标点符号等)。标记根据语言语法分为表达式和语句
C的标记化算法是“贪婪的”;它将尝试从源文本中形成尽可能长的标记,因此有时需要用空格分隔标记。例如,如果编译器看到文本“charfoo;”“
”,它会将其标记为charfoo
和;
(由于;
字符不是标识符的一部分,因此;
是一个单独的标记)。它不会将char
识别为单独的标记,因为在此阶段它不会查找特定的关键字。为了将其识别为声明,在char
和foo
之间至少需要一个空格字符:“char foo;”
.Whitespace与';“
一样,不是标识符(或任何其他标记)的一部分,因此它将char
和foo
标记相互分离。由于在此阶段,除了分隔标记外,空格没有任何意义,因此使用一个空格、十个空格还是一百个空格都无关紧要;“char foo;”
也同样有效
不过,将“*”
字符放入混合字符中,就不需要空白:“char*foo;”
将被标记为char
,*
,foo
,;
,因为'*'
字符,就像空格和';
字符一样,不是标识符的一部分。它本身就是一个独特的标记。在这些标记之间添加空格不会有什么坏处,但就编译器而言,它不会改变任何事情
因此,char*argv[]
被标记为char
,*
,argv
,[
,和]
。因为您有*
分隔char
和argv
,所以它们之间的空格大小无关紧要
此时,编译器使用语言语法确定应如何解释标记序列。char
是一个类型说明符,因此编译器假定这是声明的开始。由于这是一个声明,*
运算符被解释为一元间接运算符,而不是二进制乘法运算符
在这一点上,运算符的优先级开始发挥作用。[]
等后缀运算符的优先级高于一元运算符,因此*a[N]
被解析为*(a[N])
(a
是指针的N
-元素数组)。因此,argv
是指向char
的指针数组
不幸的是,在这一点上还有一些额外的奇怪之处;C处理数组的方式……不同于其他语言,而这个特定的声明实际上将argv
声明为指向char
的指针
然而,这是另一天的问题。编译器没有什么不同。人们根据自己或团队的偏好选择不同的样式。就编译器而言,您甚至可以编写char*argv
。底线是编译器足够聪明,能够知道何时使用将*
视为乘法
或解引用
运算符。可能是重复的谢谢大家的回答。这对我帮助很大,尽管这是我讨厌的类型…一分钟后你认为你学到了一些东西,但后来类似的东西显示出来,这完全把我甩了。谢谢
char * argv [ ]
char*argv[]