【问题标题】:Modifying Variable in Function in C在 C 中修改函数中的变量
【发布时间】:2011-10-29 20:36:33
【问题描述】:

我是 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

我在这里做错了什么?请建议对我的代码/样式进行任何违反常规约定的更改。

非常感谢!

【问题讨论】:

  • 虽然给出的答案是正确的,但您的帖子表明缺乏对 C 的理解,特别是您必须理解才能使用该语言的指针。我会推荐一本很好的 Intro To C 书,或者更专注于谷歌搜索关于 C 指针的教程。
  • 谢谢布赖恩,我一直在阅读我可以在网上和 Youtube 上找到的内容,但有时我认为当我跳进去尝试时我学得最好。
  • 很公平 - 只是想为您指明正确的方向。对于新程序员来说,指针是最难掌握的东西,但它们对于学习至关重要。
  • 我发现指针对我来说很难掌握,我主要是一个 PHP 人,涉足 Java 一点点,但不是很多。我发现我必须传递指向对象的东西而不是传递对象本身,这令人沮丧。但从我的研究来看,我真的很喜欢 C,我想我会从学习这些概念中受益

标签: c function pointers struct


【解决方案1】:

您需要通过指针传递结构:

把函数改成这样:

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

     strcpy(currentPlayer->name, name);

     currentPlayer->acceleration = acceleration;

}

然后这样称呼它:

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

编辑:

在您的原始代码中,当您将结构传递给函数时。它是“按价值”完成的。这意味着在函数中制作了一个副本。所以你在函数内部对它所做的更改将在本地副本上,不会应用于原始副本。

【讨论】:

  • 谢谢!因此,您使用箭头来访问结构属性,这是否优于点符号?一个比另一个新吗?再次感谢:)
  • 它们是不同的。当它是一个普通的结构时,你使用.。当它是一个指针时,你使用->
  • 嗯,所以我似乎收到了以 strcpy: 20 C:\Us....rc request for member 'name' in something not a structure or union开头的行的错误>
  • 太棒了,感谢您的编辑,您解释的方式很有意义
  • x->y 只是(*x).y 的语法糖。 (某些语言同时使用.。)
【解决方案2】:

您可能还想考虑“createPlayer”函数感觉好像它正在创建一个供应用程序使用的新播放器。仅当您需要在代码中使用它时才为结构分配内存,并在完成后丢弃内存,这是一种习惯且非常强大的做法。此外,这样做可以让您在运行代码时创建任意数量的“播放器”并随意使用它们。

下面是一篇文章,展示了如何使用动态内存分配(在程序执行时分配内存)来完成它。 让我们创建一个头文件 (.h) 来存放我们的定义

播放器.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 中定义的函数的实现

玩家.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;
} 

现在在您的代码的其他地方,您可以像这样使用上述函数:

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

应该做的伎俩

注意

现在我在没有使用 ac 编译器的情况下写了这一切,所以我可能会遇到一些语法错误......请从中获得 C 的感觉,而不是从字面上使用它:) 以防出现愚蠢的错误。

【讨论】:

  • 非常感谢!这真是太棒了,一个巨大的帮助
猜你喜欢
  • 1970-01-01
  • 2018-12-05
  • 2012-01-15
  • 2015-11-11
  • 1970-01-01
  • 1970-01-01
  • 2017-04-23
  • 2012-02-06
相关资源
最近更新 更多