新手编程,结构体和函数存在问题

5
嘿,我是一个新手程序员(通过C语言的cs50x学习),当他们提到结构体时,我决定尝试一下并编写一个快速程序,使用函数交换结构体中的一些值。但是我遇到了几个错误消息,其中第一个是“不兼容的指针类型,将'struct numbers *'传递给'type struct numbers *'的参数。另一个问题似乎出现在函数定义中,编译器说“类型为'struct number'的不完整定义”。我希望得到一些帮助,因为我感到困惑。

这是代码(我知道它很粗糙,但我正在学习lol)

#include <stdio.h>
struct numbers;
void swap(struct numbers* s);

int main(void)
{
    struct numbers
    {
        int a;
        int b;
        int c;
    };
    struct numbers x = {1, 5 , 9};
    swap(&x);
    printf("%i, %i, %i\n", x.a, x.b, x.c);
    return 0;
}

void swap(struct numbers* s)
{
    int temp = s -> a;
    int temp2 = s -> b;
    s -> a = s -> c;
    s -> b = temp;
    s -> c = temp2;
}

1
在主函数内定义的“struct numbers”和在任何函数外定义的“struct numbers”被认为是不同的类型。请将定义移到main之外。 - user253751
1
欢迎来到SO。虽然问题通常没什么问题,但如果下一次您发布一个问题时指定哪行引发了每个错误,将对所有人更容易。不要忘记将解决您问题的答案(如果有的话)标记为解决方案。 - SJuan76
如前所述,请将“struct”定义全局化。此外,在处理不同事物的行之间添加额外的空格(例如在您的“#include”之后,C不关心缩进)。您可能还想在“printf”中使用“%d”,这更为常见。 - Gophyr
4个回答

8
你希望在 swap() 中访问struct numbers 的字段,但是该类型的完整声明在 main() 内部,因此不可见。
将声明分离出来,使其对所有需要它的人可见。将其放在前面还可以消除预先声明结构的需要。
同样地,对于 swap() 本身,将其放在 main() 之前将消除在同一文件中需要原型的需要。
应该是这样的:
struct numbers
{
 .
 .
 .
}

static void swap(struct numbers *s)
{
 .
 .
 .
}

int main(void)
{
 .
 .
 .
}

谢谢,问题已经解决了。 - ashissl
也许值得使用 typedef,这样可以创建结构的多个实例:typedef struct { int a; int b; int c; } NUMBERS; 允许您像使用 int*float* 一样简单地编写 static void swap(NUMBERS *s) - GoBusto
当然,那很方便,但我不明白你所说的“多个实例”是什么意思。这与typedef无关,并且不是OP代码中的问题。请注意在main()中以struct numbers x =开头的行,这创建了一个实例,可以有任意数量的实例。 - unwind
@unwind 嗯,看起来我打错了;我想说的是“如果会创建多个结构体实例,使用typedef也可能很方便”。(这并不是对你的回答或任何东西的批评 - 我只是觉得没有必要单独发布。) - GoBusto

6
问题在于struct numbers声明是全局的,但定义却在main函数里,要使用结构体成员,swap函数必须知道该结构体有哪些成员,由于它无法看到定义,所以并不知道。移除声明并将定义放在全局作用域内。

4

swap函数无法看到struct numbers的定义。请将其放在main外面,使其成为全局定义。

额外提示 - 在结构体中使用typedef,可以在声明时提供更大的灵活性:

typedef struct typeNumbers
{
    int a;
    int b;
    int c;
} numbers;

请注意,typeNumbers是可选的。像这样声明它:
numbers x = {1, 2, 3};

1
问题在于结构体在主函数中,我对代码进行了一些修复并加上了注释。
#include <stdio.h>

//By defining the struct at the beginning you can avoid the forward declaration 
//and it make more sense to know what "numbers" is before continuing reading the code.
struct numbers {
    int a;
    int b;
    int c;
};

void swap(struct numbers* s)
{
    //Small change to use only one temp variable...
    int temp2 = s -> b;
    s -> b = s -> a;
    s -> a = s -> c;
    s -> c = temp2;
}

int main(void)
{
    struct numbers x = {1, 5 , 9};
    swap(&x);
    printf("%i, %i, %i\n", x.a, x.b, x.c);
    return 0;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接