0

So inside of the first loop, we intend to record new inputs to new memory locations if so why we didn't put an asterisk or ampersand to total_sum + limit_reaching?

My second question is why there's an * in sum += *(total_sum + counter); but not an &?

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    int size_of_sum;
    printf("Enter total amount of numbers you want to sum up : ");
    scanf("%d", &size_of_sum);

    int total_sum;
    total_sum = (int*) malloc (size_of_sum * sizeof(int));

    for(int limit_reaching = 0; limit_reaching < size_of_sum; limit_reaching++)
    {
        printf("Enter a number : ");
        scanf("%d", total_sum + limit_reaching);
    }

    int sum = 0;
    for(int counter = 0; counter < size_of_sum; counter++)
    {
         sum += *(total_sum + counter);
    }

    printf("Sum : %d\n", sum);

    free(total_sum);
}

I want to learn what are the roles of * in this code.

ayanova
  • 3
  • 3
  • 2
    For any pointer or array `p` and index `i`, the expression `*(p + i)` is *exactly* equal to `p[i]`. For some reason, people think that pointers must be used with pointer arithmetic, when it's not needed (well actually the compiler will translate `p[i]` *to* `*(p + i)` to there will always be pointer arithmetic). With that said, always use array-index syntax `p[i]`, since it's easier to read and understand. – Some programmer dude Aug 11 '23 at 07:50
  • 2
    `total_sum` has been declared as an `int`, not an `int *`... Perhaps re-reading the chapter on pointers would help you. – Fe2O3 Aug 11 '23 at 07:52
  • 1
    As for `total_sum + limit_reaching`, because the equivalence `p[i]` and `*(p + i)`, the expression `&p[i]` is exactly equal to `p + i`. So `total_sum + limit_reaching` is the same as `&total_sum[limit_reaching]`. ***If*** `total_sum` was declared as a pointer, which it isn't (see the comment by @Fe2O3). – Some programmer dude Aug 11 '23 at 07:53
  • 3
    On another note, in C you [should not cast the result of `malloc`](https://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc/605858). – Some programmer dude Aug 11 '23 at 07:55
  • 1
    And, on yet another note, you should be checking the return value from `scanf()`. Make that a habit!! – Fe2O3 Aug 11 '23 at 07:56
  • You should use `total_sum[counter]` instead, which is more readable, and less error prone. – Luis Colorado Aug 15 '23 at 11:07

4 Answers4

3
  • total_sum = (int*) malloc (size_of_sum * sizeof(int));

    This is invalid C, should be int* total_sum;. Do yourself a favour and stop chasing bugs that the compiler has already found for you, by following this advise: What compiler options are recommended for beginners learning C?

  • total_sum + limit_reaching Please don't use pointer arithmetic if it can be avoided. This could be written much more readable as:

    scanf("%d", &total_sum[limit_reaching]);
    

    Similarly, *(total_sum + counter) should be written as total_sum[counter].


My second question is why there's a *

Basically because the programmer was confused. The [] is so-called "syntactic sugar" for making code more readable. C guarantees that array [i] is 100% equivalent to *( (array) + (i) ). In both cases you get pointer arithmetic, but with the [] operator that happens "between the lines" and we don't have to worry about it.

In the expression total_sum + counter, total_sum is a pointer to int and so addition is carried out by total_sum number of bytes, as described below "pointer arithmetic" in any beginner level C book. So you calculate a new address with the pointer arithmetic, then dereference than one with *. But as explained above, we should rarely ever write code like that because it is bug-prone and hard to read...

For details and standard references, check out Do pointers support "array style indexing"?.

Lundin
  • 195,001
  • 40
  • 254
  • 396
  • Re "*Please don't use pointer arithmetic*", Yet you suggest `total_sum[limit_reaching]`, which is pointer arithmetic too! /// Re "*This could be written much more readable as*", wut – ikegami Aug 11 '23 at 10:52
  • @ikegami See the link at the bottom of the answer. – Lundin Aug 11 '23 at 10:58
  • I agree with it. But the OP isn't using `*(ptr + i)`, so it's not relevant here. – ikegami Aug 11 '23 at 11:00
  • @ikegami They are, later on. – Lundin Aug 11 '23 at 11:00
  • ok, but my comment was clearly not about that, and neither is what I commented on and quoted. So again, the link you asked me to check out is not relevant to my comment. – ikegami Aug 11 '23 at 11:04
1

I'm surprsied this compiles:

    int total_sum;
    total_sum = (int*) malloc (size_of_sum * sizeof(int));

You really meant to dynamically allocate an array and declare total_sum as a pointer, right? That's got to be a typo.

Better:

    int* total_sum;
    total_sum = (int*) malloc (size_of_sum * sizeof(int));

Here, total_sum is a pointer. Or more canonically, it's understood to be an array of integer of length size_of_sum.

In C, I believe you can get away with just declaring this instead of doing a malloc (and hence, skip the free call).

int total_sum[size_of_sum];

Either way, total_sum whether formally a pointer or an array, is logically treated like a pointer for most purposes in code.

So when you say:

total_sum + counter

That's equivalent to this expression:

&total_sum[counter]

Both expressions are a pointer to the position of an integer within that array (pointer).

If you want the value of that integer, you express that in code as either:

*(total_sum + counter)

The * means, "give me the value at this pointer address".

Or simply:

total_sum[counter]

Both approaches work regardless if you declared total_sum to be a malloc'd pointer or as an array.

selbie
  • 100,020
  • 15
  • 103
  • 173
  • "I'm surprsied this compiles" It doesn't compile cleanly on a conforming compiler. – Lundin Aug 11 '23 at 08:06
  • I used malloc because when I first tried to do the same by creating a variable-length argument but I received segmentation failures so I chose to use dynamic memory allocation. – ayanova Aug 12 '23 at 09:57
1

In the C language, the symbol, *, is used as the dereference operator. For pointers, it is used to retrieve values stored at the memory address of the pointer. The line scanf("%d", total_sum + limit_reaching); is reading an input from the user, the argument of this function is the memory location where you want to store your data and not a variable where you want to store it.

For the line, sum += *(total_sum + counter);, you are summing values of a pointer. To access each of its values, you have to use the operator *.

Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
Bibibou
  • 11
  • 4
0

Based on all comments and other answers: You basically want this:

Explanations in the comments.

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
  int size_of_sum;
  printf("Enter total amount of numbers you want to sum up : ");
  scanf("%d", &size_of_sum);

  int *total_sum;                                // missing '*'
  total_sum = malloc(size_of_sum * sizeof(int)); // removed useless (int*)

  for (int limit_reaching = 0; limit_reaching < size_of_sum; limit_reaching++)
  {
    printf("Enter a number : ");
    scanf("%d", &total_sum[limit_reaching]);     // using idiomatic [] syntax
  }

  int sum = 0;
  for (int counter = 0; counter < size_of_sum; counter++)
  {
    sum += total_sum[counter];               // using idiomatic [] syntax
  }

  printf("Sum : %d\n", sum);

  free(total_sum);
}

Error checking should still be added.

Jabberwocky
  • 48,281
  • 17
  • 65
  • 115