Изменение переменной в функции в C - PullRequest
4 голосов
/ 30 октября 2011

Я новичок в C, у меня есть программа, в которой я пытаюсь установить значения структуры внутри функции, но я не уверен, как передать структуру в функцию и изменить ее исходные значения.

У меня есть простая структура, которая выглядит следующим образом:

struct player {

    char name[40];
    int acceleration;

};

И просто чтобы поиграть, я делаю это:

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

Я хочу переместить эту функциональностьдля функции, чтобы я мог сделать что-то вроде этого:

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

Пока моя функция выглядит так:

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

     strcpy(currentPlayer.name, name);

     currentPlayer.acceleration = acceleration;

}

Но когда я печатаю это:

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

Я вижу это:

The speed of  is 0

Что я здесь не так делаю?Пожалуйста, предложите любые изменения в моем коде / стиле, которые противоречат обычному соглашению.

Большое спасибо!

Ответы [ 2 ]

3 голосов
/ 30 октября 2011

Вам нужно будет передать структуру по указателю:

Измените функцию следующим образом:

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

     strcpy(currentPlayer->name, name);

     currentPlayer->acceleration = acceleration;

}

И вызовите ее так:

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

РЕДАКТИРОВАТЬ:

В вашем исходном коде, когда вы передаете структуру в функцию.Это делается «по стоимости».Это означает, что копия сделана в функцию.Поэтому изменения, внесенные вами в функцию, будут в локальной копии и не будут применены к исходной копии.

1 голос
/ 30 октября 2011

Возможно, вы также захотите учесть, что функция «createPlayer» выглядит так, как будто она создает новый проигрыватель для использования приложением.Обычно и очень полезно выделять память для структуры только тогда, когда вам требуется использовать ее в коде, и отбрасывать память, когда вы закончите.Кроме того, это позволит вам создавать столько «игроков», сколько вы хотите, когда вы запускаете код, и использовать их по своему усмотрению.

Ниже приведен пост, показывающий, как это можно сделать с помощью динамического выделения памяти (выделения памяти при выполнении программы).Давайте создадим файл заголовка (.h), в котором будут храниться наши определения

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 */

. Давайте создадим player.c, который будет содержать реализацию функций, определенных в 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 */

Определить функции для управления распределением структуры

/* 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;
} 

Теперь в другом месте вашего кода вы можете использовать вышеуказанную функцию, например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);
      }
}

скомпилируйте программу с обоими файлами c, используя ваш компилятор c (добавьте их в свой проект, если вы используете C IDE).построить проект ....

В случае, если вы используете командную строку, тогда:

cc -o player_test player.c main.c

должно сделать трюк

NOTE

Теперь я написал все это без использования AC-компилятора, поэтому у меня могут быть некоторые синтаксические ошибки ... пожалуйста, получите представление о C, а не используйте его буквально :) в случаеесть глупые ошибки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...