在 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,例如 externstatictypedef... and/or 类型限定符,例如 constvolatile。正在定义的标识符前面有一个星号表示这个变量是一个指针,多个星号表示多级间接。

在表达式中,星号可以作为二元运算符出现在操作数之间,也可以作为一元运算符出现在其操作数之前。二元运算符 * 是乘法运算符,而一元运算符 * 是解引用运算符。

根据经验,标识符或后缀运算符后面的 * 是乘法运算符。后缀运算符是 ++--、使用 [] 进行索引并在 ().

中调用带有可选参数的函数

混淆来自于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个变量xpn。 * p 是指向 int 的指针,而 xnint 变量。 * x 初始化为 0 * p被初始化为x的地址。 * n 的初始化器是 p 指向的值乘以自身的结果。

在同一定义中定义具有不同间接级别的多个变量是不受欢迎的,因为它令人困惑且容易出错。强烈建议在 3 行中重写上述定义:

 int x = 0;
 int *p = &x;
 int n = *p * *p;