Newbie question

Discussion in 'C Programming' started by vadud3, Jan 2, 2005.

  1. vadud3

    vadud3 Guest

    Hi All

    I am trying to compile the following program:

    #include <stdio.h>
    #include <string.h>

    typedef struct employee {
    int id;
    char name[10];
    float salary;
    } e;

    void processEmp(e); //supply function prototype with structure alias
    name

    main()
    {
    e empl = {0,'\0',0}; //Initialize members

    processEmp (empl); //pass structure by value

    printf("\nID: %d\n", empl.id);
    printf("Name: %s\n", empl.name);
    printf("Salary : $%.2f\n", empl.salary);
    } // end main

    void processEmp(e emp) //receives a copy of the structure
    {
    emp.id = 123;
    strcpy(emp.name, "Sheila");
    emp.salary = 65000.00;
    } //end processEmp


    I compile it using gcc 3.3.2 on Mandrake 10.2 like this

    gcc program.c

    But when I run ./a.out it shows

    ID: 0
    Name:
    Salary : $0.00

    I was expecting the output be like this:

    ID: 123
    Name: Sheila
    Salary : $65000.00

    Any thing I am doing wrong?

    Thanks for the help
    vadud3, Jan 2, 2005
    #1
    1. Advertising

  2. vadud3

    Ben Pfaff Guest

    "vadud3" <> writes:

    > processEmp (empl); //pass structure by value


    [...]

    > void processEmp(e emp) //receives a copy of the structure
    > {
    > emp.id = 123;
    > strcpy(emp.name, "Sheila");
    > emp.salary = 65000.00;
    > } //end processEmp


    You seem to have a fundamental misunderstanding of what "pass by
    value" means. Look it up in your book again.
    --
    Ben Pfaff
    email:
    web: http://benpfaff.org
    Ben Pfaff, Jan 2, 2005
    #2
    1. Advertising

  3. vadud3 wrote:
    > Hi All
    >
    > I am trying to compile the following program:


    OP's code replaced with:

    #include <stdio.h>
    #include <string.h>

    typedef struct employee
    {
    int id;
    char name[10];
    float salary;
    } employee;

    void processEmp(employee *); /* note */

    int main(void) /* note */
    {
    employee empl = { 0, "", 0 }; /* note */
    processEmp(&empl); /* note */
    printf("\nID: %d\n", empl.id);
    printf("Name: %s\n", empl.name);
    printf("Salary : $%.2f\n", empl.salary);
    return 0; /* note */
    }

    void processEmp(employee * emp) /* note */
    {
    emp->id = 123; /* note */
    strcpy(emp->name, "Sheila"); /* note */
    emp->salary = 65000.00; /* note */
    }


    [output]
    ID: 123
    Name: Sheila
    Salary : $65000.00
    Martin Ambuhl, Jan 2, 2005
    #3
  4. vadud3

    vadud3 Guest

    That was how it was exactly in the book. I wonder if there might be
    something very simple that came from the book as typo.
    vadud3, Jan 2, 2005
    #4
  5. vadud3

    -berlin.de Guest

    vadud3 <> wrote:
    > That was how it was exactly in the book. I wonder if there might be
    > something very simple that came from the book as typo.


    Then it might a good idea to throw away that book and get a better one.
    It can't be a single typo and there are also several other problems with
    the program.

    > #include <stdio.h>
    > #include <string.h>
    >
    > typedef struct employee {
    > int id;
    > char name[10];
    > float salary;
    > } e;
    >
    > void processEmp(e); //supply function prototype with structure alias
    > name


    At least for posts in newsgroups better use the traditional "/*" and
    "*/" comment delimiters - it makes it less error prone for others that
    try to copy and paste the code when lines are too long and get broken
    by the newsreader. Moreover, comments starting with "//" became only
    legal with the newer C99 standard and they might get you into problems
    with older compilers.

    > main()


    main() is a function that returns an int. Relying on that being the
    default isn't an option anymore if your program is to be compiled
    with a C99 compliant compiler. And it's also clearer to specify the
    arguments main() is supposed to accept, i.e. none. So make that line

    int main( void )

    > {
    > e empl = {0,'\0',0}; //Initialize members


    The second member of the employee structure is a char array, not a
    char, so the initialization must be either

    e empl = { 0, "", 0 };

    or

    e empl = { 0, { '\0' }, 0};

    > processEmp (empl); //pass structure by value


    And this means that the function receives a copy of the structure.
    Everything done by that function gets done to the copy it received
    but not to the structure you have in the caller of the function,
    which remains unchanged. As Martin Ambuhl already pointed out you
    can correct that by passing a pointer to the structure to the func-
    tion and operate on the structure belonging to the caller via this
    pointer. Another option would be to have the function return the
    modified structure and to assign this return value to 'empl'.

    > printf("\nID: %d\n", empl.id);
    > printf("Name: %s\n", empl.name);
    > printf("Salary : $%.2f\n", empl.salary);
    > } // end main


    Since main() returns an int you're missing a return statement here.
    Use either

    return EXIT_SUCCESS;

    (but then you need to include <stdlib.h>) or

    return 0;

    on successful exit from main().

    Some of the problems the compiler can tell you about if you invoke it
    with the appropriate options. In the case of gcc I would recommend to
    use at least "-W -Wall" - it then will warn you about code that is
    problematic.
    Regards, Jens
    --
    \ Jens Thoms Toerring ___ -berlin.de
    \__________________________ http://www.toerring.de
    -berlin.de, Jan 2, 2005
    #5
  6. On 1 Jan 2005 23:06:28 -0800, "vadud3" <> wrote:

    >That was how it was exactly in the book. I wonder if there might be
    >something very simple that came from the book as typo.


    If you tell us which book, we can add it to the list of ones to be
    avoided.


    <<Remove the del for email>>
    Barry Schwarz, Jan 2, 2005
    #6
  7. vadud3

    Darklight Guest

    It looks like you are using linux so may i suggest you use the following
    commands IE:

    gcc -Wall file.c

    to compile will give you better error output
    or

    gcc -Wall -ggdb file.c -o file

    which will enable you to run the ddd debugger but it must be installed
    then to run the debbeger you type ddd file
    file being the executable file

    right i am a beginner so the program you wrote is below with the
    modifications i made the rest you will have to work out for your self.

    #include <stdio.h>
    #include <string.h>

    struct employee {
    int id;
    char name[10];
    float salary;
    }emp;

    void processEmp(void); /*supply function prototype with structure alias*/

    int main(void)
    {
    processEmp (void); /*pass structure by value*/

    printf("\nID: %d\n", emp.id);
    printf("Name: %s\n", emp.name);
    printf("Salary : $%.2f\n", emp.salary);
    return 0;
    } /* end main */

    void processEmp(void) /*receives a copy of the structure*/
    {
    emp.id = 123;
    strcpy(emp.name, "Sheila");
    emp.salary = 65000.00;
    } /*end processEmp*/
    Darklight, Jan 2, 2005
    #7
  8. vadud3

    Michael Mair Guest

    Darklight wrote:
    > It looks like you are using linux so may i suggest you use the following
    > commands IE:
    >
    > gcc -Wall file.c


    More important: Tell the compiler that you want to have standard
    conforming C!

    gcc -Wall -ansi -pedantic

    If you add weak optimisation, you get more information about
    unused variables and the like:

    gcc -O -Wall -ansi -pedantic

    If you want to have whatever C99 gcc already has, use -std=c99 instead
    of -ansi.
    If you do not want to type this all the time, use an alias for gcc.

    > to compile will give you better error output
    > or
    >
    > gcc -Wall -ggdb file.c -o file
    >
    > which will enable you to run the ddd debugger but it must be installed
    > then to run the debbeger you type ddd file
    > file being the executable file


    ddd works on top of gdb, hence the -ggdb.
    This option does not give you more warnings but makes the code
    debuggable by leaving correlations between lines in source and
    the executed object code in the object file.
    I would use extensive debug information if any: -g3 or -ggdb3
    This makes macros partially usable in debugging (the ## and #
    operators do not work).

    > right i am a beginner so the program you wrote is below with the
    > modifications i made the rest you will have to work out for your self.
    >
    > #include <stdio.h>
    > #include <string.h>
    >
    > struct employee {
    > int id;
    > char name[10];
    > float salary;
    > }emp;


    You are declaring (and using) a global variable emp. This is a
    Bad Idea in many if not most situations; if you do not understand
    that then be careful with "advice" you give to other people.


    > void processEmp(void); /*supply function prototype with structure alias*/


    We have a function which does not get passed anything and returns
    nothing. The comment is definitely wrong.

    >
    > int main(void)
    > {
    > processEmp (void); /*pass structure by value*/


    The comment is wrong. It should read:
    /* Initialise global variable emp */

    >
    > printf("\nID: %d\n", emp.id);
    > printf("Name: %s\n", emp.name);
    > printf("Salary : $%.2f\n", emp.salary);
    > return 0;
    > } /* end main */
    >
    > void processEmp(void) /*receives a copy of the structure*/


    Once more: The comment is bogus.

    > {
    > emp.id = 123;
    > strcpy(emp.name, "Sheila");


    Careful: either check whether strlen("Sheila")+1<=sizeof(emp.name)
    or use strncpy() or your own safe version of it.

    > emp.salary = 65000.00;
    > } /*end processEmp*/


    If you work only on global variables, you run into trouble whenever
    you need another variable: You have to double the number of functions
    even if the functions do essentially the same.
    Read up on this and the structural dangers of using global variables.

    For the OP: Stay with Martin Ambuhl's solution and ask if you
    do not understand it from the comments already given in the
    thread.


    Cheers
    Michael
    --
    E-Mail: Mine is an /at/ gmx /dot/ de address.
    Michael Mair, Jan 2, 2005
    #8
  9. vadud3

    Flash Gordon Guest

    Darklight wrote:
    > It looks like you are using linux so may i suggest you use the following
    > commands IE:
    >
    > gcc -Wall file.c


    Around here you should really use -ansi -pedantic as well, so that you
    invoke it as a conforming C compiler. Adding -O allows another warning
    to be generated.

    gcc -ansi -pedantic -Wall -O file.c

    > to compile will give you better error output
    > or
    >
    > gcc -Wall -ggdb file.c -o file


    gcc -ansi -pedantic -Wall -O -g file.c -o file

    > which will enable you to run the ddd debugger but it must be installed
    > then to run the debbeger you type ddd file
    > file being the executable file
    >
    > right i am a beginner so the program you wrote is below with the
    > modifications i made the rest you will have to work out for your self.
    >
    > #include <stdio.h>
    > #include <string.h>
    >
    > struct employee {
    > int id;
    > char name[10];
    > float salary;
    > }emp;


    Using globals is generally a *bad* idea.

    > void processEmp(void); /*supply function prototype with structure alias*/


    You are write to supply a function prototype. However, see comments
    about how this problem should have been solved.

    > int main(void)
    > {
    > processEmp (void); /*pass structure by value*/


    Your comment is now completely wrong. A good way to confuse people.

    > printf("\nID: %d\n", emp.id);
    > printf("Name: %s\n", emp.name);
    > printf("Salary : $%.2f\n", emp.salary);
    > return 0;
    > } /* end main */
    >
    > void processEmp(void) /*receives a copy of the structure*/


    Your comment is now completely wrong. A good way to confuse people.

    > {
    > emp.id = 123;
    > strcpy(emp.name, "Sheila");
    > emp.salary = 65000.00;
    > } /*end processEmp*/


    I suggest you look at the other replies. Using a global variable is
    *not* the right thing to do. You either pass a pointer to the struct or
    make the function return the struct.
    --
    Flash Gordon
    Living in interesting times.
    Although my email address says spam, it is real and I read it.
    Flash Gordon, Jan 2, 2005
    #9
  10. vadud3 wrote on 02/01/05 :
    > That was how it was exactly in the book. I wonder if there might be
    > something very simple that came from the book as typo.


    Name the book.

    I guess that the idea of this exercise is to demonstrate that passing a
    structure has no effect on it. If not, burn the book.

    --
    Emmanuel
    The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
    The C-library: http://www.dinkumware.com/refxc.html

    "C is a sharp tool"
    Emmanuel Delahaye, Jan 2, 2005
    #10
  11. vadud3 wrote:
    > Hi All
    >
    > I am trying to compile the following program:
    >
    > #include <stdio.h>
    > #include <string.h>
    >
    > typedef struct employee {
    > int id;
    > char name[10];
    > float salary;
    > } e;
    >
    > void processEmp(e); //supply function prototype with structure alias
    > name
    >
    > main()
    > {
    > e empl = {0,'\0',0}; //Initialize members
    >
    > processEmp (empl); //pass structure by value
    >
    > printf("\nID: %d\n", empl.id);
    > printf("Name: %s\n", empl.name);
    > printf("Salary : $%.2f\n", empl.salary);
    > } // end main
    >
    > void processEmp(e emp) //receives a copy of the structure
    > {
    > emp.id = 123;
    > strcpy(emp.name, "Sheila");
    > emp.salary = 65000.00;
    > } //end processEmp
    >
    >
    > I compile it using gcc 3.3.2 on Mandrake 10.2 like this
    >
    > gcc program.c
    >
    > But when I run ./a.out it shows
    >
    > ID: 0
    > Name:
    > Salary : $0.00
    >
    > I was expecting the output be like this:
    >
    > ID: 123
    > Name: Sheila
    > Salary : $65000.00
    >
    > Any thing I am doing wrong?
    >
    > Thanks for the help
    >


    I would suggest you drop the book you are reading. Get a better book
    like the one written by K. N. King (C Programming: A Modern Approach).
    Steer clear from Schildt's stuff, unless you want an exercise finding bugs.

    Regards,
    Jonathan
    Jonathan Burd, Jan 5, 2005
    #11
  12. vadud3

    Chris Torek Guest

    >vadud3 <> wrote:
    [snippage]
    >> typedef struct employee {
    >> int id;
    >> char name[10];
    >> float salary;
    >> } e;

    [and]
    >> e empl = {0,'\0',0}; //Initialize members


    In article <>
    <-berlin.de> wrote:
    >The second member of the employee structure is a char array, not a
    >char, so the initialization must be either
    >
    >e empl = { 0, "", 0 };
    >
    >or
    >
    >e empl = { 0, { '\0' }, 0};


    While either of these is, in my opinion, clearly *superior*, it
    is not the case that these are *required* (implied by the words
    "must be"). Without additional bracketing, what we have is, in
    effect:

    {
    empl.id = 0,
    empl.name[0] = '\0',
    empl.name[1] = 0
    /*
    * empl.name[2] = 0 -- no explicit initializer, hence defaulted
    * empl.name[3] = 0 -- no explicit initializer
    * .
    * .
    * .
    * empl.name[9] = 0 -- no explicit initializer
    * empl.salary = 0 -- no explicit initializer
    */
    }

    Without explicit initializers for the listed elements, the fact
    that there is some initializer at all causes the rest of the
    initializers to be created implicitly by the compiler as if you
    had explicitly asked for each one to be set to 0.

    This is the same rule that, given:

    void f(void) {
    char buf[12345] = { 0 };
    ...
    }

    forces the C compiler to initialize all 12345 elements of the
    array "buf" to 0. If we change the source to:

    void f(void) {
    char buf[12345];
    buf[0] = 0;
    ...
    }

    the compiler is not obligated to zero out all 12344 remaining
    elements, and most will indeed not do so. (In a few rare cases,
    this can even make f() run faster-enough to notice. :) )
    --
    In-Real-Life: Chris Torek, Wind River Systems
    Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
    email: forget about it http://web.torek.net/torek/index.html
    Reading email is like searching for food in the garbage, thanks to spammers.
    Chris Torek, Jan 11, 2005
    #12
  13. vadud3

    -berlin.de Guest

    Chris Torek <> wrote:
    >>vadud3 <> wrote:

    > [snippage]
    >>> typedef struct employee {
    >>> int id;
    >>> char name[10];
    >>> float salary;
    >>> } e;

    > [and]
    >>> e empl = {0,'\0',0}; //Initialize members


    > In article <>
    > <-berlin.de> wrote:
    >>The second member of the employee structure is a char array, not a
    >>char, so the initialization must be either
    >>
    >>e empl = { 0, "", 0 };
    >>
    >>or
    >>
    >>e empl = { 0, { '\0' }, 0};


    > While either of these is, in my opinion, clearly *superior*, it
    > is not the case that these are *required* (implied by the words
    > "must be").


    Thanks for the clarification. The "must be" was wrong unless under-
    stood in the sense that it doesn't do what the OP probably meant the
    code to do, i.e. an initialization of

    empl.id = 0;
    empl.name[0] = '\0';
    empl.salary = 0;

    and that it wouldn't work as expected with e.g.

    e empl = { 0, '\0', 10 };

    because in that case empl.salary wouldn't be set to 10, as I guess
    the OP did assume, but empl.name[1].

    Regards, Jens
    --
    \ Jens Thoms Toerring ___ -berlin.de
    \__________________________ http://www.toerring.de
    -berlin.de, Jan 15, 2005
    #13
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Jerry C.
    Replies:
    8
    Views:
    207
    Uri Guttman
    Nov 23, 2003
  2. Kruno Saho
    Replies:
    0
    Views:
    125
    Kruno Saho
    Apr 7, 2013
  3. Dave Angel
    Replies:
    0
    Views:
    110
    Dave Angel
    Apr 7, 2013
  4. rusi
    Replies:
    0
    Views:
    100
  5. Miki Tebeka
    Replies:
    0
    Views:
    74
    Miki Tebeka
    Apr 7, 2013
Loading...

Share This Page