Pass-by-reference to nested function?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • S.

    Pass-by-reference to nested function?

    Hi all,

    I have the requirement that I must pass-by-reference to my function
    addStudent() and getAge() functions where my getAge() function is
    within the addStudent() function. I am able to pass-by-reference to
    the first function, addStudent() but then I am confused as to how I am
    suppose to pass the pointer of 'student' from within the addStudent()
    function to the getAge() function that is nested within the
    addStudent() function.

    My code below does not compile correctly with the inclusion of the
    getAge() function and I receive the following compile warning:
    "test2.c", line 30: warning: left operand of "->" must be pointer
    to struct/union
    where line 30 is:
    scanf("%d", student->age);

    I understand this is not the "simplest" way to achieve the inputs for
    the student's name and age but it is my requirement to have the nested
    functions and to pass variables by reference. Thanks for your help in
    advance.

    S.

    #include <stdio.h>
    #define NAME_SIZE 20
    #define CLASS_SIZE 10

    typedef struct {
    char name[20];
    int age;
    } Student;

    void addStudent(Stud ent *student);
    void getAge(Student **student);

    void main() {
    Student students[CLASS_SIZE];
    addStudent(&stu dents[3]);
    return;
    }

    /* Pass-by-reference */
    void addStudent(Stud ent *student) {
    printf("\nStude nt name: ");
    scanf("%s", student->name);
    printf("\nStude nt age: ");
    getAge(&student );
    return;
    }

    /* Pass-by-reference */
    void getAge(Student **student) {
    scanf("%d", student->age);
    return;
    }
  • Richard Tobin

    #2
    Re: Pass-by-reference to nested function?

    In article <02f6dd75-4fd9-45f9-86dc-362fd84c5814@i3 6g2000prf.googl egroups.com>,
    S. <sianeagles@gma il.comwrote:
    >I have the requirement that I must pass-by-reference to my function
    >addStudent() and getAge() functions where my getAge() function is
    >within the addStudent() function. I am able to pass-by-reference to
    >the first function, addStudent() but then I am confused as to how I am
    >suppose to pass the pointer of 'student' from within the addStudent()
    >function to the getAge() function that is nested within the
    >addStudent() function.
    You achieve the effect of pass-by-reference in C by explicitly passing
    a pointer. Both your functions, addStudent() and getAge(), want to
    receive a Student by reference, so they should both declare a
    pointer-to-student as their argument.

    So this is right:
    >void addStudent(Stud ent *student) {
    and this call is right:
    addStudent(&stu dents[3]);
    because students[3] is of type Student, so you have to use ampersand
    to get a pointer to it.

    This is wrong though:
    >void getAge(Student **student) {
    It should be Student *student, just as in addStudent(), and this call:
    getAge(&student );
    should just be getAge(student) because student is already a pointer.

    By the way, this is a very bad idea in real code:
    scanf("%s", student->name);
    because it tries to read a string of unknown length. You declared
    Student as:
    >typedef struct {
    char name[20];
    int age;
    >} Student;
    (did you mean to use NAME_SIZE which you defined as 20?), so what will
    happen if the user type in a 30-character name? Look up scanf() to
    see how to limit the string length.

    -- Richard
    --
    :wq

    Comment

    • Chris Thomasson

      #3
      Re: Pass-by-reference to nested function?

      "Richard Tobin" <richard@cogsci .ed.ac.ukwrote in message
      news:g05btc$2r2 q$1@pc-news.cogsci.ed. ac.uk...
      In article
      <02f6dd75-4fd9-45f9-86dc-362fd84c5814@i3 6g2000prf.googl egroups.com>,
      S. <sianeagles@gma il.comwrote:
      >
      [...]
      (did you mean to use NAME_SIZE which you defined as 20?), so what will
      happen if the user type in a 30-character name? Look up scanf() to
      see how to limit the string length.
      Here is a simple way to setup fixed length string formatters in scanf what
      will work with the NAME_SIZE macro:
      _______________ _______________ _______________ _______________ ________
      #include <stdio.h>

      #define PLACE_X(t)t
      #define PLACE(t)t
      #define QUOTE_X2(t)#t
      #define QUOTE_X1(t)PLAC E_X(QUOTE_X2)t
      #define QUOTE(t)QUOTE_X 1((t))

      #define NAME_SIZE 10

      int main() {
      char name[NAME_SIZE + 1] = { '\0' };
      printf("Enter Name: ");
      if (scanf(QUOTE(%P LACE(NAME_SIZE) s), name) == 1) {
      printf("\n\nYou r Name Is: %s\n", name);
      }
      return 0;
      }

      _______________ _______________ _______________ _______________ ________



      Comment

      • S.

        #4
        Re: Pass-by-reference to nested function?

        Hi Richard,

        Thank you so much. Your comments not only fixed my problem but also
        helped me with understanding pointers.

        You are also right about your other tips in regards to NAME_SIZE and
        the name array. I am fixing those aspects of the code as we speak.

        Kind regards,
        S.

        On May 11, 9:42 am, rich...@cogsci. ed.ac.uk (Richard Tobin) wrote:
        In article <02f6dd75-4fd9-45f9-86dc-362fd84c5...@i3 6g2000prf.googl egroups.com>,
        >
        S. <sianeag...@gma il.comwrote:
        I have the requirement that I must pass-by-reference to my function
        addStudent() and getAge() functions where my getAge() function is
        within the addStudent() function. I am able to pass-by-reference to
        the first function, addStudent() but then I am confused as to how I am
        suppose to pass the pointer of 'student' from within the addStudent()
        function to the getAge() function that is nested within the
        addStudent() function.
        >
        You achieve the effect of pass-by-reference in C by explicitly passing
        a pointer. Both your functions, addStudent() and getAge(), want to
        receive a Student by reference, so they should both declare a
        pointer-to-student as their argument.
        >
        So this is right:
        >
        void addStudent(Stud ent *student) {
        >
        and this call is right:
        >
        addStudent(&stu dents[3]);
        >
        because students[3] is of type Student, so you have to use ampersand
        to get a pointer to it.
        >
        This is wrong though:
        >
        void getAge(Student **student) {
        >
        It should be Student *student, just as in addStudent(), and this call:
        >
        getAge(&student );
        >
        should just be getAge(student) because student is already a pointer.
        >
        By the way, this is a very bad idea in real code:
        >
        scanf("%s", student->name);
        >
        because it tries to read a string of unknown length. You declared
        Student as:
        >
        typedef struct {
        char name[20];
        int age;
        } Student;
        >
        (did you mean to use NAME_SIZE which you defined as 20?), so what will
        happen if the user type in a 30-character name? Look up scanf() to
        see how to limit the string length.
        >
        -- Richard
        --
        :wq

        Comment

        • Richard Heathfield

          #5
          Re: Pass-by-reference to nested function?

          S. said:
          Hi all,
          >
          I have the requirement that I must pass-by-reference to my function
          Tricky, that, in C. C uses pass-by-value for all parameter-passing.

          <snip>
          My code below does not compile correctly with the inclusion of the
          getAge() function and I receive the following compile warning:
          "test2.c", line 30: warning: left operand of "->" must be pointer
          to struct/union
          where line 30 is:
          scanf("%d", student->age);
          Let's take a look at the student object, then, shall we?
          typedef struct {
          char name[20];
          int age;
          } Student;
          Presumably that's the type.
          void addStudent(Stud ent *student);
          void getAge(Student **student);
          >
          void main() {
          In C, main returns int. Learn this. Mark it well. Engrave it on your heart,
          your soul, and your wristwatch strap. In C, main returns int.
          Student students[CLASS_SIZE];
          addStudent(&stu dents[3]);
          That's fine. students[3] is a Student object, so &students[3] is a pointer
          to a Student object.
          return;
          }
          >
          /* Pass-by-reference */
          void addStudent(Stud ent *student) {
          That pointer sure looks to me as if it's being passed by value.
          printf("\nStude nt name: ");
          scanf("%s", student->name);
          Unwise. Anyone who types in a name as long as ZoroastrianPent angle (or
          anything longer) will overrun memory that it shouldn't, possibly resulting
          in bizarre outcomes. I recommend you do some research into fgets.
          printf("\nStude nt age: ");
          getAge(&student );
          Okay, that's legal, and passes a copy of the VALUE of the address of this
          pointer to getAge().
          return;
          }
          >
          /* Pass-by-reference */
          Sure looks like pass-by-value to me.
          void getAge(Student **student) {
          scanf("%d", student->age);
          -requires on its left side a pointer to struct. You don't have one. You
          have a pointer to pointer to struct. This will work:

          int getAge(Student **student) {
          return scanf("%d", &(*student)->age);
          }

          (note the & because scanf requires a pointer to a valid int, not the int
          value itself) but one wonders why you are bothering to do this, since you
          don't use the fact that, in this getAge function, student is a pointer to
          a pointer. Why not lose a * and just do:

          int getAge(Student *student) {
          return scanf("%d", &student->age);
          }

          and make appropriate adjustments in the caller? If your reason is that
          "then it wouldn't be pass by reference", well, it isn't pass by reference
          anyway, so no loss there. In fact, why not just pass a pointer to the age?

          int getAge(int *ageptr) {
          return scanf("%d", ageptr);
          }

          In fact, why bother with the function at all?

          --
          Richard Heathfield <http://www.cpax.org.uk >
          Email: -http://www. +rjh@
          Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
          "Usenet is a strange place" - dmr 29 July 1999

          Comment

          Working...