【问题标题】:C file can't see a variable declared in included fileC文件看不到包含文件中声明的变量
【发布时间】:2018-03-20 11:06:21
【问题描述】:

我有三个文件。 test.ctest.huse.c。他们每个人的代码如下所示:

test.h:

#pragma once

#define unused __attribute__((unused))

typedef int cmd_fun_t(struct tokens *tokens);
typedef struct fun_desc {
  cmd_fun_t *fun;
  char *cmd;
  char *doc;
} fun_desc_t;

int cmd_exit(struct tokens *tokens);
int cmd_help(struct tokens *tokens);
int cmd_pwd(struct tokens *tokens);
int cmd_cd(struct tokens *tokens);

test.c:

#include <ctype.h>
#include <errno.h>
#include <stdbool.h>
#include <stdio.h>
#include <readline/readline.h>
#include <readline/history.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <signal.h>
#include <sys/wait.h>
#include <termios.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/signal.h>

#include "test.h"
#include "tokenizer.h"


fun_desc_t cmd_table[] = {
  {cmd_help, "?", "show this help menu"},
  {cmd_exit, "exit", "exit the command shell"},
  {cmd_pwd, "pwd", "print working directory"},
  {cmd_cd, "cd", "change directory"},
};

int cmd_pwd(unused struct tokens *tokens){
  char cwd[8192];
  if (getcwd(cwd, sizeof(cwd)) != NULL)
      fprintf(stdout, "%s\n", cwd);
  else
      perror("Error Occured");

  return 1;
}

int cmd_cd(unused struct tokens *tokens){
  if(chdir(tokens_get_token(tokens, 1)) == -1){
    fprintf(stdout, "No such file or directory.\n");
    return -1;
  }

  return 1;
}

/* Prints a helpful description for the given command */
int cmd_help(unused struct tokens *tokens) {
  for (unsigned int i = 0; i < sizeof(cmd_table) / sizeof(fun_desc_t); i++)
    printf("%s - %s\n", cmd_table[i].cmd, cmd_table[i].doc);
  return 1;
}

/* Exits this shell */
int cmd_exit(unused struct tokens *tokens) {
  exit(0);
}

使用.c:

#include "test.h"
int main(){
    for(int i = 0; i < sizeof(cmd_table); i++){

    }
    return 0;
}

我的假设是这应该很好,但是当我编译代码时,它给出了以下错误:

‘cmd_table’未声明(在此函数中首次使用)for(int i = 0; i

有什么建议为什么会发生这种情况?

【问题讨论】:

  • 您认为sizeof(cmd_table) 究竟应该是什么?我不明白这一点。 cmd_table 仍然在 .c 文件中声明,该文件不在 use.c 的范围内。
  • 是的,但它是全球性的。不应该 use.c 查看 test.c 的全局变量
  • 你能编译 test.c 吗?
  • 是什么让你认为use.c 可以“看到”cmd_table
  • ...无论如何从test.c 外部访问cmd_table 是糟糕的设计。

标签: c file compiler-errors compilation header


【解决方案1】:

cmd_tabletest.c 中定义。如果您希望它在编译其他 C 文件时对编译器可见,则在编译其他文件时需要有一个可见的 extern 声明。通常的做法是将extern 声明放在标题中。

// in test.h
extern fun_desc_t cmd_table[];

不幸的是,这并不能告诉你数组有多大。对于像这样的查找表,解决此问题的常用方法是在末尾放置一个空标记值。

fun_desc_t cmd_table[] = {
  {cmd_help, "?", "show this help menu"},
  {cmd_exit, "exit", "exit the command shell"},
  {cmd_pwd, "pwd", "print working directory"},
  {cmd_cd, "cd", "change directory"},
  {NULL, NULL, NULL}
};

你改变main中的循环如下

int main()
{
    for(int i = 0; cmd_table[i].fun != NULL; i++)
    {
        // Do whatever
    }
    return 0;
}    

【讨论】:

  • 正确答案,但这样做是糟糕的设计。
  • @MichaelWalz 好吧,我也在考虑提供一个完全封装的解决方案,但现在是午餐时间,我很饿。
【解决方案2】:

cmd_table 在 test.c 文件中声明,您在 use.c 文件中使用它。由于 cmd_table 的范围仅限于 test.c 文件,因此您不能在 use.c 文件中使用它

【讨论】:

  • 我只是把它放在 c 文件中,但是现在当我编译它说 cmd_table 是在其他地方定义的,这绝对不是
  • 我将它移到标题中,现在编译说它在其他地方定义,但事实并非如此。我检查了很多次,它不是
  • 你需要在头文件中声明extern变量才能在两个.c文件中使用它
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-29
  • 1970-01-01
  • 1970-01-01
  • 2011-08-30
  • 2016-11-03
相关资源
最近更新 更多