简体   繁体   中英

Modifying Variable in Function in C

I am a beginner at C, I have a program where I'm trying to set values of a structure inside a function, but I'm unsure of how to pass the structure to the function and have it modify it's original values.

I have a simple structure that looks like this:

struct player {

    char name[40];
    int acceleration;

};

And just to play around I do this:

struct player terry;
terry.acceleration = 20;
strcpy(terry.name, "John Terry");

I want to move this functionality to a function so I can do something like this:

createPlayer(terry, 20, "John Terry");

So far my function looks like this:

void createPlayer(struct player currentPlayer, char name[], int acceleration) {

     strcpy(currentPlayer.name, name);

     currentPlayer.acceleration = acceleration;

}

But when I print this:

printf("The speed of %s is %d \n\n", terry.name, terry.acceleration);

I see this:

The speed of  is 0

What am I doing wrong here? Please suggest any changes to my code / style that goes against the usual convention.

Thank you so much!

You'll need to pass the struct by pointer:

Change the function to this:

void createPlayer(struct player *currentPlayer, char name[], int acceleration) {

     strcpy(currentPlayer->name, name);

     currentPlayer->acceleration = acceleration;

}

And call it like this:

createPlayer(&terry, 20, "John Terry");

EDIT:

In your original code, when you pass the struct into the function. It is done "by value". This means that a copy is made into the function. So what changes you make to it inside the function will be on the local copy and will not be applied to the original copy.

You may also want to consider that "createPlayer" function feels as if it's creating a new player for use by the application. It is customary and very powerful to allocate memory for the structure only when you require to use it in the code, and discard the memory when you are done. Also, doing so will allow you to create as many "players" as you want when you are running the code and use them as you like.

Below is a post to show how it may be done using dynamic memory allocation (allocating memory when the program is executed). let's create a header file (.h) that will house our definitions

player.h:

/* this player.h header file is used by other parts of our program to access
 * the player functionality definitions and interface 
 */

/* the #ifndef / #define below protects against inadvertent syntax errors
 * that may occur by double inclusion of the same file.
 */

#ifndef _PLAYER_H 
#define _PLAYER_H

struct player {

    char name[40];
    int acceleration;

};

extern struct player * create_player(const char *name, int acceleration);
void delete_player(struct player *p);
const char * get_player_name(struct player *p);
void set_player_name(struct player *p, const char *name);
int get_player_accel(struct player *p);
void set_player_accel(struct player *p, int accel);

/* you can add other functions here and then define their implementation in player.c
   shown below */

#endif /* _PLAYER_H */

let's create a player.c that will contain the implementation of the functions defined in player.h

player.c:

/* include memory management functions */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "player.h" /* we created this above */


/* Define the structure */

Define the functions to manage the structure allocation

/* create_player function allocates memory for a new player structure 
 *  and returns the pointer to it upon succcess. It returns NULL on failure 
 */
struct player * create_player(const char *name, int acceleration) {
       struct player *new_player = malloc(sizeof(struct player));
       /* malloc allocates memory for the sizeof the structure and returns
          the pointer to it */
       if ( !new_player ) {
             /* typically we don't put error messages in production code
              * it is handled elsewhere but verbosity 
              * is okay for learning, so we add an error message */
             fprintf(stderr, "unable to allocate memory for a new player\n");
             return NULL;
       }
} 

/* delete_player deallocates memory that was allocated in create_player
 * only pass it the pointers that were created by create_player structure
 */

void delete_player(struct player *p) {
     if (p)
        free(p); 
} 

/* let's do some house keeping functions */


const char * get_player_name(struct player *p) {
      if ( p ) 
           return p->name;
      else 
           return NULL;
}

void set_player_name(struct player *p, const char *name) {
     if ( p ) {
           strncpy(p->name, name, sizeof(p->name)); /* only 40 characters */
     }
}

int get_player_accel(struct player *p) {
    return p->acceleration;
} 

void set_player_accel(struct player *p, int accel) {
    if ( p ) 
         p->acceleration = accel;
} 

Now elsewhere in your code you can use the above function like this:

main.c:

#include <stdio.h>
#include "player.h"

int main() {
      struct player *player = create_player("john", 30);

      if ( player ) { 
               printf("%s's acceleration is %d\n", player->name, player->acceleration);
      }
}

compile the program with both c files using your c compiler (add them to your project if you are using a C IDE). build the project... .

In case you are using command line then:

cc -o player_test player.c main.c

should do the trick

NOTE

Now i wrote this all out without without using ac compiler so i may have some syntax errors ... please get the feeling of C from it, rather than using it literally :) in case there are silly mistakes.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM