在C中 - 我在做什么错

  • 本文关键字: c global-variables extern
  • 更新时间 :
  • 英文 :


我正在玩耍,在C中制作一个小棋子,因为我多年来都没有碰过C。

我的主要测试是一个非常简单的测试:

#include "ChessGame.h"
int main()
{
    initializeNewGame();
    onLift('a', '2');
    onSet('a', '3');
}

InitializeNewGame()将清除一些缓冲区,并初始化板。板是一个简单的结构,定义为:

CHESSBOARDSTRUCTURE.H:

struct chessboard
{
    char board[8][8];
};
struct chessboard* board;

调用初始化时,它会使用一个称为Chessboard.h的标头。该标头有责任检查用户是否遵守规则。它也知道如何使董事会归化。

Chessboard.c

#include "chessBoardStructure.h"
extern struct chessboard * board;
void initializeBoard()
{
    board = malloc(sizeof(struct chessboard));
    /* Sets the array to the right chars */
 }

现在,从我的理解中,我现在应该定义全局变量,板。为了验证我从InitializeNewGame()调用InitializeBoard()之后打印出板。一切都很好。

现在InitializeGame()返回到MAIN,onLift()被调用。这应该验证一些规则。问题是,当onLift()在Chessgame.c中称为:

ChessGame.C 外部结构棋盘*板;

void onLift(char col, char row)
{
    short err = getValidMoves(liftedCol, liftedRow, &validEndPoints, &validRoads, board);
    if (err == -1)
        handleBadPiece();
    /* Do stuff */
}

董事会刚好为-51。当我在标头的板上设置手表时,我会看到它是初始化的,然后当InitializeGame()退出范围时,它变成了良好的OL' -51。

我在这里做错了什么?

我想念C 。: - (

谢谢!

编辑小示例我试图按建议改变周围的外部,但也发生了同样的事情。请参见下面的示例。

main.c

#include "a.h"
int main()
{
    masterInitialize();
    printData();
    return 0;
}

(仅由于声明而未显示标题(

A.C

#include "a.h"
#include "b.h"
#include "struct.h"
#include <stdio.h>
struct mystruct* datastruct;
void masterInitialize()
{
    initializeDataStruct();
}
void printData()
{
    for (int i = 0; i < 10; i++)
        printf("Data: %cn", datastruct->data[i]);
}

b.c

#include "b.h"
#include "struct.h"
#include <stdlib.h>
struct mystruct* datastruct;
void initializeDataStruct()
{
    datastruct = malloc(sizeof(struct mystruct));
    for (int i = 0; i < 10; i++)
        datastruct->data[i] = 1;
}

struct.h

struct mystruct
{
    char data[10];
};
extern struct mystruct* datastruct;

你有错误的方式。

这应该在" Chessboard.c"中。

struct chessboard* board;

这应该在您的标题中

extern struct chessboard * board;

因为这将告诉所有您包含在哪里的文件,该文件存在在某个地方声明的变量board,在链接时间,它将使用您在" Chessboard.c"中声明的一个文件。

使用您当前的方式,包括标头的每个C文件都有其自己的唯一版本的board

extern struct chessboard * board; dewine nothing;它只是声明了标识符board,并且它是类型的指针到某处的struct chessboard

struct chessboard* board;是(暂定(定义。它定义了一个具有外部链接和静态存储持续时间的单个变量。但是,您已将其放入随附的源文件中,该文件包含在几个地方。因此,在#include s的每个地方,此文件都会对board进行冲突的定义。

Linux上的

GCC将在单独的翻译单元中合并多个定义,但C标准不指出。相反,它说(C11 6.9:

5 [...]如果在表达式中使用了带有外部链接的标识符(作为sizeof或_alignof运算符的操作数的一部分,其结果是整数常数(,则在整个程序中的某个地方应完全是标识符的一个外部定义;否则,不得超过一个。

在您的代码中,同一标识符有多个定义,这会导致您的程序具有不确定的行为,因为C11 4P2:

如果A ''warm''或" warge nonge"要求出现在约束或运行时 - 约束之外的要求,行为是未定义的。> [...]


但是(我想是(Posix规定了通用扩展J.5.11:

J.5.11多个外部定义

,对于对象的标识符,可能有一个以上的外部定义,无论是否明确使用关键字extern;如果定义不同意,或者是一个以上的初始化,则该行为是不确定的(6.9.2(。

相关内容

  • 没有找到相关文章

最新更新