mallocdynamic-memory-allocationrealloccalloc

How do you easily differentiate the use of * as a pointer, * as a de-reference operator, * as a multiplication operator in C?


The use of * is all so confusing especially for us new comers to C. I mean, how do you easily differentiate the use of * as a pointer, * as a de-reference operator, * as a multiplication operator? I see alot of different use of * online and it's quite confusing, especially regarding different positions of the * e.g. as in the sample code below. What positions of * are correct and advisable to use to avoid confusion with pointers, de-referencing and multiplication? Code is just sample and may...infact will not compile.

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: I'm new in C and pls don't refer me to useless links and ("supposedly") duplicates that doesn't answer exactly same question as this...pls allow others to air their views so we get maximum answers, none knows it all, u will be surprised that something new can pop-up, even for the so called C old-timers.


Solution

  • When you read C code, you must be able to distinguish definitions and expressions. A definition starts with a type optionally preceded by a storage class such as typedef, extern, static... and/or type qualifiers such as const and, volatile. A star in front of the identifier being defined indicates that this variable is a pointer, multiple stars indicate multiple levels of indirection.

    In an expression, a star can occur as a binary operator, between operands, or as unary operator, in front of its operand. The binary operator * is the multiplication operator, whereas the unary * is the dereference operator.

    As a rule of thumb, a * that follows an identifier or a postfix operator is a multiplication operator. Postfix operators are ++, --, indexing with [] and calling a function with optional arguments inside ().

    The confusion comes from the conciseness of the C language, which allows the programmer to combine these different uses at will:

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

    This ugly line is indeed confusing. Let's first insert meaningful spaces to improve readability:

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

    Spacing is mostly unnecessary for the C compiler, but following simple rules increases readability for humans:

    The above line of code defines 3 variables x, p and n.

    Defining multiple variables with different levels of indirection in the same definition is frowned upon because it is confusing and error prone. Rewriting the above definition on 3 lines is highly advisable:

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