在 C 语言中,如何轻松区分 * 作为指针、* 作为取消引用运算符、* 作为乘法运算符的用法?
How do you easily differentiate the use of * as a pointer, * as a de-reference operator, * as a multiplication operator in C?
*
的使用非常令人困惑,尤其是对于我们这些刚接触 C 语言的人来说。我的意思是,您如何轻松区分 *
作为指针的用法,*
作为取消引用运算符,*
作为乘法运算符?我在网上看到很多 *
的不同用法,这很令人困惑,尤其是 *
的不同位置,例如如下面的示例代码所示。 *
的哪些位置是正确的并且建议使用以避免与指针、取消引用和乘法混淆?
代码只是示例,可能...实际上不会编译。
int main(void){
int *size, length, width;
*size1= malloc(sizeof(int) * length);
*size2= (int *) malloc(width * sizeof(int) * width);
*size3= malloc(sizeof(int) *length);
printf("%d\n%d\n%d\n", size1,size2,size3);
return (0);
}
N.B:我是 C 语言的新手,请不要向我推荐无用的链接和 ("supposedly") 不能回答与此完全相同的问题的重复...请允许其他人发表他们的观点,以便我们得到最大的答案,none 知道这一切,即使对于所谓的 C 老前辈,你也会惊讶地发现新的东西会弹出。
当你阅读C代码时,你必须能够区分定义和表达式。定义以类型开头,前面可选地存储 class,例如 extern
、static
、typedef
... and/or 类型限定符,例如 const
和 volatile
。正在定义的标识符前面有一个星号表示这个变量是一个指针,多个星号表示多级间接。
在表达式中,星号可以作为二元运算符出现在操作数之间,也可以作为一元运算符出现在其操作数之前。二元运算符 *
是乘法运算符,而一元运算符 *
是解引用运算符。
根据经验,标识符或后缀运算符后面的 *
是乘法运算符。后缀运算符是 ++
、--
、使用 []
进行索引并在 ()
.
中调用带有可选参数的函数
混淆来自于C语言的简洁,它允许程序员随意组合这些不同的用途:
int x=0,*p=&x,n=*p**p;
这条丑陋的线确实令人困惑。让我们先插入有意义的 spaces 以提高可读性:
int x = 0, *p = &x, n = *p * *p;
C 编译器基本上不需要空格,但遵循简单的规则可以提高人类的可读性:
- 在二元运算符两边加一个space
- 在
,
和 ;
之后添加一个 space 除了行尾
- 不要在一元运算符及其操作数之间插入 space,
sizeof
除外。
- 以一致的方式缩进代码,通常每级 4 spaces
上面这行代码定义了3个变量x
、p
和n
。
* p
是指向 int
的指针,而 x
和 n
是 int
变量。
* x
初始化为 0
* p
被初始化为x
的地址。
* n
的初始化器是 p
指向的值乘以自身的结果。
在同一定义中定义具有不同间接级别的多个变量是不受欢迎的,因为它令人困惑且容易出错。强烈建议在 3 行中重写上述定义:
int x = 0;
int *p = &x;
int n = *p * *p;
*
的使用非常令人困惑,尤其是对于我们这些刚接触 C 语言的人来说。我的意思是,您如何轻松区分 *
作为指针的用法,*
作为取消引用运算符,*
作为乘法运算符?我在网上看到很多 *
的不同用法,这很令人困惑,尤其是 *
的不同位置,例如如下面的示例代码所示。 *
的哪些位置是正确的并且建议使用以避免与指针、取消引用和乘法混淆?
代码只是示例,可能...实际上不会编译。
int main(void){
int *size, length, width;
*size1= malloc(sizeof(int) * length);
*size2= (int *) malloc(width * sizeof(int) * width);
*size3= malloc(sizeof(int) *length);
printf("%d\n%d\n%d\n", size1,size2,size3);
return (0);
}
N.B:我是 C 语言的新手,请不要向我推荐无用的链接和 ("supposedly") 不能回答与此完全相同的问题的重复...请允许其他人发表他们的观点,以便我们得到最大的答案,none 知道这一切,即使对于所谓的 C 老前辈,你也会惊讶地发现新的东西会弹出。
当你阅读C代码时,你必须能够区分定义和表达式。定义以类型开头,前面可选地存储 class,例如 extern
、static
、typedef
... and/or 类型限定符,例如 const
和 volatile
。正在定义的标识符前面有一个星号表示这个变量是一个指针,多个星号表示多级间接。
在表达式中,星号可以作为二元运算符出现在操作数之间,也可以作为一元运算符出现在其操作数之前。二元运算符 *
是乘法运算符,而一元运算符 *
是解引用运算符。
根据经验,标识符或后缀运算符后面的 *
是乘法运算符。后缀运算符是 ++
、--
、使用 []
进行索引并在 ()
.
混淆来自于C语言的简洁,它允许程序员随意组合这些不同的用途:
int x=0,*p=&x,n=*p**p;
这条丑陋的线确实令人困惑。让我们先插入有意义的 spaces 以提高可读性:
int x = 0, *p = &x, n = *p * *p;
C 编译器基本上不需要空格,但遵循简单的规则可以提高人类的可读性:
- 在二元运算符两边加一个space
- 在
,
和;
之后添加一个 space 除了行尾 - 不要在一元运算符及其操作数之间插入 space,
sizeof
除外。 - 以一致的方式缩进代码,通常每级 4 spaces
上面这行代码定义了3个变量x
、p
和n
。
* p
是指向 int
的指针,而 x
和 n
是 int
变量。
* x
初始化为 0
* p
被初始化为x
的地址。
* n
的初始化器是 p
指向的值乘以自身的结果。
在同一定义中定义具有不同间接级别的多个变量是不受欢迎的,因为它令人困惑且容易出错。强烈建议在 3 行中重写上述定义:
int x = 0;
int *p = &x;
int n = *p * *p;