如何轻松区分 C 中 * 作为指针、* 作为解引用运算符、* 作为乘法运算符的使用?

问题描述 投票:0回答:1

*
的使用非常令人困惑,尤其是对于我们这些 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);
}

NB:我是 C 语言新手,请不要向我推荐无用的链接和(“据说”)重复的内容,这些链接和答案与此不完全相同……请允许其他人发表他们的观点,以便我们得到最大的帮助答案,没有人知道这一切,你会惊讶地发现一些新的东西会弹出,即使对于所谓的 C 老前辈来说也是如此。

malloc dynamic-memory-allocation realloc calloc
1个回答
1
投票

当你阅读C代码时,你必须能够区分定义和表达式。定义以类型开头,可选地前面带有存储类,例如

typedef
extern
static
...和/或类型限定符,例如
const
volatile
。定义的标识符前面有一个星号表示该变量是一个指针,多个星号表示多层间接。

在表达式中,星号可以作为二元运算符出现在操作数之间,也可以作为一元运算符出现在其操作数前面。二元运算符

*
是乘法运算符,而一元
*
是解引用运算符。

根据经验,标识符或后缀运算符后面的

*
是乘法运算符。后缀运算符是
++
--
,使用
[]
进行索引并在
()
内调用带有可选参数的函数。

混乱来自于C语言的简洁性,它允许程序员随意组合这些不同的用途:

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

这丑陋的线条确实令人困惑。让我们首先插入有意义的空格以提高可读性:

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

对于 C 编译器来说,空格基本上是不必要的,但遵循简单的规则可以提高人类的可读性:

  • 二元运算符两边加一个空格
  • ,
    ;
    之后添加一个空格(行尾除外)
  • 不要在一元运算符与其操作数之间插入空格,
    sizeof
    除外。
  • 以一致的方式缩进代码,通常每层缩进 4 个空格

上面这行代码定义了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;
© www.soinside.com 2019 - 2024. All rights reserved.