Thread: Assigning value to structure members using -> operator

  1. #1
    Registered User
    Join Date
    Jun 2018
    Posts
    26

    Assigning value to structure members using -> operator

    Code:
    #include<stdio.h>
    #include<stdlib.h>
    struct person {
       int age;
       float weight;
       char name[30];
    };
    
    int main()
    {
       struct person *ptr;
       int i, num;
    
       printf("Enter number of persons: ");
       scanf("%d",&num);
    
       ptr =(struct person*) malloc(num *sizeof(struct person));
       // Above statement allocates the memory for n structures with pointer personPtr pointing to base address */
    
       for(i =0; i < num;++i)
       {
           printf("Enter name, age and weight of the person respectively:\n");
           scanf("%s%d%f",&(ptr+i)->name,&(ptr+i)->age,&(ptr+i)->weight);
       }
    
       printf("Displaying Infromation:\n");
       for(i =0; i < num;++i)
           printf("%s\t%d\t%.2f\n",(ptr+i)->name,(ptr+i)->age,(ptr+i)->weight);
    
       return0;
    }
    I'm still struggling with some concepts of C programming language.In the above program, when structure members set value using scanf, what is the need of & in front of ptr

    i.e.,
    Code:
    &(ptr+i)->name


    when giving variables values directly(with out using scanf)

    Code:
    ptr->name = "Athul";
    is enough

    also

    Code:
    int a;
    scanf("%d", &a);
    here we are telling to store the user input to the address of variable a.

    Since Pointer ptr is already an address, what is the need of putting & in front of it??

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    I appreciate that you're trying to figure out the syntax, but I suggest that you don't do things that way. Let's look at your print loop:
    Code:
    for(i =0; i < num;++i)
       printf("%s\t%d\t%.2f\n",(ptr+i)->name,(ptr+i)->age,(ptr+i)->weight);
    This is fine, but because you are iterating by index, we would more commonly use array index syntax:
    Code:
    for (i = 0; i < num; ++i)
       printf("%s\t%d\t%.2f\n", ptr[i].name, ptr[i].age, ptr[i].weight);
    As you can see, this makes it a bit easier to reason: ptr[i] is the "current element" in each iteration.

    If you want to use pointer syntax, then work with pointers, e.g.,
    Code:
    struct person *end;
    for (end = ptr + num; ptr != end; ++ptr)
       printf("%s\t%d\t%.2f\n", ptr->name, ptr->age, ptr->weight);
    As you can see, by iterating with a pointer instead of an index, we don't need to do pointer arithmetic beyond incrementing the pointer, as long as we aren't say, trying to access other elements in the array via the pointer. This is because now ptr is the "pointer to the current element" in each iteration.

    So, back to your question. It looks like &(ptr+i)->name is actually wrong. It should indeed have been just (ptr+i)->name. Again, if you had used array index notation to match your iteration by index:
    Code:
    for (i = 0; i < num; ++i)
    {
       printf("Enter name, age and weight of the person respectively:\n");
       scanf("%s%d%f", ptr[i].name, &ptr[i].age, &ptr[i].weight);
    }
    whereas if you actually want to work with pointers proper:
    Code:
    struct person *end;
    for (end = ptr + num; ptr != end; ++ptr)
    {
       printf("Enter name, age and weight of the person respectively:\n");
       scanf("%s%d%f", ptr->name, &ptr->age, &ptr->weight);
    }
    By the way, you should check the return value of scanf to see if the read was successful.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Jun 2018
    Posts
    26
    changing this

    Code:
    for(i =0; i < num;++i)
       {
           printf("Enter name, age and weight of the person respectively:\n");
           scanf("%s%d%f",&(ptr+i)->name,&(ptr+i)->age,&(ptr+i)->weight);
       }
    
    
    to this

    Code:
    for(i =0; i < num;++i)
       {
           printf("Enter name, age and weight of the person respectively:\n");
           scanf("%s%d%f",(ptr+i)->name,(ptr+i)->age,(ptr+i)->weight);
       }
    give Segmentation fault
    Last edited by Athul; 09-21-2018 at 02:58 AM.

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    You removed some necessary & from your scanf call.

    Use a better compiler to tell you when you get this wrong.
    Code:
    $ gcc -Wall foo.c
    foo.c: In function ‘main’:
    foo.c:23:14: warning: format ‘%d’ expects argument of type ‘int *’, but argument 3 has type ‘int’ [-Wformat=]
            scanf("%s%d%f",(ptr+i)->name,(ptr+i)->age,(ptr+i)->weight);
                  ^
    foo.c:23:14: warning: format ‘%f’ expects argument of type ‘float *’, but argument 4 has type ‘double’ [-Wformat=]
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Registered User
    Join Date
    Jun 2018
    Posts
    26
    That was my question, need of & in ptr, even though ptr is already the address

    In the first answer i got for this post

    So, back to your question. It looks like &(ptr+i)->name is actually wrong. It should indeed have been just (ptr+i)->name

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Exactly. Notice that I didn't say anything about &(ptr+i)->age or &(ptr+i)->weight, because you wrote that "Since Pointer ptr is already an address, what is the need of putting & in front of it?", so I assumed that you understood that this was for the name member only, as name is an array thus it will be converted to a pointer to its first element, whereas age and weight are neither arrays nor pointers.

    EDIT:
    Oh! Sorry. I realised that I misread your statement. Unfortunately, you are wrong in what you were looking at. Yes, ptr, being a pointer, contains an address, but you are not passing ptr as an argument. You are passing &(ptr+i)->name as the argument.

    Put it another way: before you start trying to learn about how to use this syntax, you should learn how to use scanf with arrays and structures, e.g., you should understand why this is wrong:
    Code:
    struct person x;
    scanf("%s%d%f", x.name, x.age, x.weight);
    and why this is technically wrong, even though it may work:
    Code:
    struct person x;
    scanf("%s%d%f", &x.name, &x.age, &x.weight);
    but this is correct (disregarding the possible buffer overflow):
    Code:
    struct person x;
    scanf("%s%d%f", x.name, &x.age, &x.weight);
    Last edited by laserlight; 09-21-2018 at 04:06 AM.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #7
    Registered User
    Join Date
    Jun 2018
    Posts
    26
    Thanks for clarifying the difference

    I understand how this works

    Code:
    struct person x;
    scanf("%s%d%f", x.name, &x.age, &x.weight);
    
    
    or

    Code:
    scanf("%s%d%f",&(*ptr).name,&(*ptr).age,&(*ptr).weight);
    Here user input is assigned to age and weight variable by referring their address like a normal variable

    i.e

    Code:
    int a;
    scanf("%d", &a);

    But when we use pointer, consider the above example of int a

    Code:
    int a;
    int *ptr = &a;
    scanf("%d", ptr);
    Here I don't have to write

    Code:
    scanf("%d", &ptr);
    since pointer ptr itself represent the address

    But in structure

    I've to use &


    Code:
    for(i =0; i < num;++i)
       {
           printf("Enter name, age and weight of the person respectively:\n");
           scanf("%s%d%f",(ptr+i)->name,&(ptr+i)->age,&(ptr+i)->weight);
       }
    
    For me it seems like for a same situation, two rules (But I know there's a difference between both, that's what I'm looking for)
    Last edited by Athul; 09-21-2018 at 04:45 AM.

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Athul
    Here user input is assigned to age and weight variable by referring their address like a normal variable
    Other than spelling, (*ptr).age is exactly the same as ptr->age. They are the same thing, so &(*ptr).age is the same thing as &ptr->age.

    Quote Originally Posted by Athul
    Here I don't have to write

    Code:
    scanf("%d", &ptr);
    since pointer ptr itself represent the address
    ptr contains the address of the int object named a. This is critical, because that's exactly the same thing as what you are doing to read the age member of the struct person object.

    Quote Originally Posted by Athul
    But in structure

    I've to use &


    Code:
    for(i =0; i < num;++i)
       {
           printf("Enter name, age and weight of the person respectively:\n");
           scanf("%s%d%f",(ptr+i)->name,&(ptr+i)->age,&(ptr+i)->weight);
       }
    
    For me it seems like for a same situation, two rules (But I know there's a difference between both, that's what I'm looking for)
    It is the same situation, except that you confused yourself by forgetting that your aim is to read into the members of the struct person object, not the struct person object itself. You are not writing &ptr, which is the address of ptr. You are writing &(ptr + i)->age, which is the address of the age member of the ith struct person object in the array.

    To break it down:
    ptr is a pointer to the first element of the struct person array
    (ptr + i) is a pointer to the ith element of the struct person array
    (ptr + i)->age is the age member of the ith element of the struct person array; this is equivalent to (*(ptr + i)).age and ptr[i].age
    &(ptr + i)->age is the address of the age member of the ith element of the struct person array

    Notice that at no point do you write &ptr and leave it as that, therefore at no point do you pass the address of ptr as an argument to scanf.
    Last edited by laserlight; 09-21-2018 at 05:25 AM.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  9. #9
    Registered User
    Join Date
    Jun 2018
    Posts
    26
    This is &(ptr + i)->age in fact same as this &((ptr + i)->age)


    That makes sense

    Thanks

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 4
    Last Post: 12-06-2017, 06:23 PM
  2. Replies: 12
    Last Post: 03-27-2017, 02:06 AM
  3. assigning a structure as a unit
    By johnmerlino in forum C Programming
    Replies: 12
    Last Post: 02-22-2014, 05:09 AM
  4. How to find number of structure members in a given structure?
    By bhaskarReddy in forum C Programming
    Replies: 4
    Last Post: 01-16-2012, 05:37 AM
  5. Replies: 2
    Last Post: 05-12-2010, 10:10 AM

Tags for this Thread