C语言多文件电话簿程序gcc编译报错如何解决
编译错误解决方案
错误1&2:variably modified ‘hashtable’ at file scope
原因
C语言要求文件作用域的数组长度必须是编译期可确定的常量,你当前用unsigned int CAPACITY = 100定义的是普通变量,不能作为全局数组的长度。同时头文件中直接定义全局变量,会导致所有包含该头文件的.c文件都生成一份变量副本,最终链接时重复定义。
修复方法
- 修改
phonehead.h,将CAPACITY改为宏定义,全局hashtable改为extern声明,同时增加头文件守卫防止重复包含:
// 增加头文件守卫 #ifndef PHONEHEAD_H #define PHONEHEAD_H #include <stdio.h> #include <stdlib.h> #include <cs50.h> #include <stdint.h> #include <string.h> // 用宏定义编译期常量 #define CAPACITY 100 typedef struct node { char name[20]; struct node* link; } node; // 全局变量仅在头文件声明,不定义 extern struct node* hashtable[CAPACITY] ; unsigned int hash(char* buffer , unsigned int CAPACITY) ; void import_names(void) ; void add_name(string name) ; void search_for(string name) ; void delete_name(string name) ; #endif
- 在任意一个
.c文件(比如Request.c)中定义全局hashtable:
// Request.c开头加这句,放在#include之后 struct node* hashtable[CAPACITY];
错误3:redefinition of ‘struct node’
原因
Search.c已经引入了包含struct node定义的phonehead.h,你又在Search.c中重复写了一遍typedef struct node的定义,同时Request.c、Import.c也存在同样的重复定义问题。
修复方法
删除Search.c、Request.c、Import.c中自己写的struct node类型定义,所有.c文件统一引入phonehead.h复用类型定义。
比如修改后的Search.c开头只需要保留:
#include "phonehead.h" // 删掉下面这段重复的struct node定义 // typedef struct node // { // char name[20]; // struct node* link; // } // node; // 也删掉重复定义的CAPACITY和hashtable
Request.c和Import.c同理,删掉自己写的struct node定义,开头加上#include "phonehead.h"。
其他附带问题修复
你代码中还有其他会导致运行错误的问题,建议同步修复:
- 编译命令拼写错误:你写的
requist.c和实际文件名Request.c不匹配,修正编译命令为:
gcc Request.c Import.c Hash.c Search.c -o phone
注意不要把头文件
phonehead.h放到gcc编译参数里,头文件会自动被.c文件引入
Import.c中自己定义了局部的hashtable,导致导入的姓名没有存到全局hashtable,其他函数完全读不到导入的数据。删掉Import.c中struct node* hashtable[CAPACITY] ;这句,直接操作全局的hashtable即可。- 命令行参数判断逻辑错误:
if(argc != 3 || argc != 4)永远为真,修改为if(argc <3 || argc>4)。 exit是函数,要加括号调用:所有单独写的exit ;改为exit(1);。fgets读取的姓名末尾会带换行符,和用户输入的姓名不匹配,导入时需要去掉换行:buffer[strcspn(buffer, "\n")] = '\0';
内容的提问来源于stack exchange,提问作者Moe Hasan
相关产品推荐
相关产品推荐

