| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 861 人关注过本帖
标题:<c 程序语言>第一章最后一段程序,编译报错
只看楼主 加入收藏
myhyperion
Rank: 1
等 级:新手上路
帖 子:5
专家分:0
注 册:2014-5-30
结帖率:0
收藏
已结贴  问题点数:20 回复次数:10 
<c 程序语言>第一章最后一段程序,编译报错
cc outVar.c
Undefined symbols for architecture x86_64:
"_line", referenced from:
_mycopy in outVar-c483d3.o
_mygetLine in outVar-c483d3.o
"_longest", referenced from:
_main in outVar-c483d3.o
_mycopy in outVar-c483d3.o
"_max", referenced from:
_main in outVar-c483d3.o
"_mygetline", referenced from:
_main in outVar-c483d3.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)


全部代码如下:
程序代码:
#include <stdio.h>
#define MAXLINE 100
int mygetline(void);
void mycopy(void);
int main(int argc, const char *argv[])
{
int len;
extern int max;
extern char longest[];
max = 0;
while((len = mygetline()) > 0){
if(len > max){
max = len;
mycopy();
}
}
if(max > 0)
printf("%s", longest);
return 0;
}
int mygetLine(void)
{
int c, i;
extern char line[];
for (i = 0; i < MAXLINE-1 && (c = getchar()) != EOF && c != '\n'; i++) {
line[i] = c;
}
if(c == '\n'){
line[i] = c;
++i;
}
line[i] = '\0';
return i;
}
void mycopy(void){
int i;
extern char line[], longest[];
i = 0;
while((longest[i] = line[i]) != '\0')
++i;
}
搜索更多相关主题的帖子: 程序语言 command symbols failed 
2014-05-30 09:37
pangshch
Rank: 10Rank: 10Rank: 10
等 级:青峰侠
威 望:2
帖 子:443
专家分:1966
注 册:2013-4-9
收藏
得分:5 
主要问题是程序里面的外部变量,如extern char longest[];只有声明,没有把定义这个变量的文件一起编译。
int mygetLine(void)  // 这里的L是大写的, 而你其它地方的是小写l
{
int c, i;
extern char line[];
for (i = 0; i < MAXLINE-1 && (c = getchar()) != EOF && c != '\n'; i++) {
line[i] = c;
}
2014-05-30 11:06
砖家的谎言
Rank: 12Rank: 12Rank: 12
等 级:禁止访问
威 望:30
帖 子:693
专家分:3898
注 册:2013-12-6
收藏
得分:5 
printf("%s", longest);  字符数组能这样打印吗?

我不是砖家,要努力成为砖家。
2014-05-30 11:08
myhyperion
Rank: 1
等 级:新手上路
帖 子:5
专家分:0
注 册:2014-5-30
收藏
得分:0 
以下是引用pangshch在2014-5-30 11:06:51的发言:

主要问题是程序里面的外部变量,如extern char longest[];只有声明,没有把定义这个变量的文件一起编译。
int mygetLine(void)  // 这里的L是大写的, 而你其它地方的是小写l
{
int c, i;
extern char line[];
for (i = 0; i < MAXLINE-1 && (c = getchar()) != EOF && c != '\n'; i++) {
line = c;
}

那个大写是个问题,但改完后还是不能通过。
如果是声明的问题的话,请问怎么改才好?如果就这一个文件的话。

另外我把书上的说法陈列出来:
关于extern, 书上是这个说法:
在该例子中,前几行定义了 main、getline 与 copy 函数使用的几个外部变量,声明 了各外部变量的类型,这样编译程序将为它们分配存储单元。从语法角度看,外部变量的定 义与局部变量的定义是相同的,但由于它们位于各函数的外部,因此这些变量是外部变量。 函数在使用外部变量之前,必须要知道外部变量的名字。要达到该目的,一种方式是在函数 中使用 extern 类型的声明。这种类型的声明除了在前面加了一个关键字 extern 外,其它 方面与普通变量的声明相同。
某些情况下可以省略 extern 声明。在源文件中,如果外部变量的定义出现在使用它的 函数之前,那么在那个函数中就没有必要使用 extern 声明。因此,main、getline 及 copy 中的几个 extern 声明都是多余的。在通常的做法中,所有外部变量的定义都放在源文件的 开始处,这样就可以省略 extern 声明。
如果程序包含在多个源文件中,而某个变量在 file1 文件中定义、在 file2 和 file3 文件中使用,那么在文件 file2 与 file3 中就需要使用 extern 声明来建立该变量与其定 义之间的联系。人们通常把变量和函数的 extern 声明放在一个单独的文件中(习惯上称之 为头文件),并在每个源文件的开头使用#include 语句把所要用的头文件包含进来。后缀 名.h 约定为头文件名的扩展名。例如,标准库中的函数就是在类似于<stdio.h>的头文件中 声明的。更详细的信息将在第 4 章中讨论,第 7 章及附录 B 将讨论函数库。
在上述特别版本中,由于 getline 与 copy 函数都不带参数,因此从逻辑上讲,在源文 件开始处它们的原型应该是 getline()与 copy()。但为了与老版本的 C 语言程序兼容, ANSI C 语言把空参数表看成老版本 C 语言的声明方式,并且对参数表不再进行任何检查。在 ANSI C中,如果要声明空参数表,则必须使用关键字void进行显式声明。第4章将对此进 一步讨论。
在该例子中,前几行定义了 main、getline 与 copy 函数使用的几个外部变量,声明 了各外部变量的类型,这样编译程序将为它们分配存储单元。从语法角度看,外部变量的定 义与局部变量的定义是相同的,但由于它们位于各函数的外部,因此这些变量是外部变量。 函数在使用外部变量之前,必须要知道外部变量的名字。要达到该目的,一种方式是在函数 中使用 extern 类型的声明。这种类型的声明除了在前面加了一个关键字 extern 外,其它 方面与普通变量的声明相同。
某些情况下可以省略 extern 声明。在源文件中,如果外部变量的定义出现在使用它的 函数之前,那么在那个函数中就没有必要使用 extern 声明。因此,main、getline 及 copy 中的几个 extern 声明都是多余的。在通常的做法中,所有外部变量的定义都放在源文件的 开始处,这样就可以省略 extern 声明。
如果程序包含在多个源文件中,而某个变量在 file1 文件中定义、在 file2 和 file3 文件中使用,那么在文件 file2 与 file3 中就需要使用 extern 声明来建立该变量与其定 义之间的联系。人们通常把变量和函数的 extern 声明放在一个单独的文件中(习惯上称之 为头文件),并在每个源文件的开头使用#include 语句把所要用的头文件包含进来。后缀 名.h 约定为头文件名的扩展名。例如,标准库中的函数就是在类似于<stdio.h>的头文件中 声明的。更详细的信息将在第 4 章中讨论,第 7 章及附录 B 将讨论函数库。
在上述特别版本中,由于 getline 与 copy 函数都不带参数,因此从逻辑上讲,在源文 件开始处它们的原型应该是 getline()与 copy()。但为了与老版本的 C 语言程序兼容, ANSI C 语言把空参数表看成老版本 C 语言的声明方式,并且对参数表不再进行任何检查。在 ANSI C中,如果要声明空参数表,则必须使用关键字void进行显式声明。第4章将对此进 一步讨论。
2014-05-30 11:23
pangshch
Rank: 10Rank: 10Rank: 10
等 级:青峰侠
威 望:2
帖 子:443
专家分:1966
注 册:2013-4-9
收藏
得分:0 
回复 4 楼 myhyperion
第一种方法: 在同一个文件中定义外部变量
程序代码:
#include <stdio.h>
#define MAXLINE 100

int max;                 // 在这里定义外部变量, 这样,下面函数体中的extern 关键字可以省略。
char longest[100];     
char line[100];

int mygetline(void);
void mycopy(void);
int main(int argc, const char *argv[])
{
第二种方法,
如果你把外部变量的定义放在别的文件中了, 那要把那个文件和你现在的文件一起编译或包含。
如你把上面三个变量定义在了file1.c中,而你现在在file2.c中要使用, 那就要把两个文件一起编译,在file1.c中,要像上面第一种方法一样定义变量, 在file2.c中, 要用extern关键字声明.
头文件包含的情况,
如,你把上面那三个变量放在一个叫head.h的头文件中, 那么使用的时候要在程序最前面 如:#include <stdio.h> 的位置加上#include <head.h>。
2014-05-30 11:56
myhyperion
Rank: 1
等 级:新手上路
帖 子:5
专家分:0
注 册:2014-5-30
收藏
得分:0 
回复 5 楼 pangshch
我试了一下,在前面声明
char longest[MAXLINE];
char line[MAXLINE];
后编译通过了。然后下了个英文版看了下,是中文版少了两行代码。

不过“在源文件中,如果外部变量的定义出现在使用它的 函数之前,那么在那个函数中就没有必要使用 extern 声明。因此,main、getline 及 copy 中的几个 extern 声明都是多余的。”。 我把extern去除了后,又报错了:
outVar.c:15:10: error: definition of variable with array type needs an explicit size or an initializer
    char longest[];
         ^
outVar.c:34:10: error: definition of variable with array type needs an explicit size or an initializer
    char line[];
         ^
outVar.c:51:10: error: definition of variable with array type needs an explicit size or an initializer
    char line[], longest[];
         ^
outVar.c:51:18: error: definition of variable with array type needs an explicit size or an initializer
    char line[], longest[];
                 ^

但是前面已经声明过了啊,不是应该直接使用外面的变量才对吗?
2014-05-30 13:04
myhyperion
Rank: 1
等 级:新手上路
帖 子:5
专家分:0
注 册:2014-5-30
收藏
得分:0 
回复 6 楼 myhyperion
然后我把里面引用的那些数组也加入了size:
   char line[MAXLINE]
之类的,当然没有在函数内部使用extern而是在前面声明。
编译通过了,执行结果却是:
  cpractise  ./a.out   
1
32
1324
h?%
2014-05-30 14:14
zklhp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:china
等 级:贵宾
威 望:254
帖 子:11485
专家分:33241
注 册:2007-7-10
收藏
得分:5 
这是clang编译的么

都说clang的出错信息友好 我怎么感觉这里很一般呢
2014-05-30 16:51
pangshch
Rank: 10Rank: 10Rank: 10
等 级:青峰侠
威 望:2
帖 子:443
专家分:1966
注 册:2013-4-9
收藏
得分:0 
回复 7 楼 myhyperion
extern int max;  // 把函数里面的这种语句整个删除。
extern char longest[];
在外面定义了之后, 函数里的的extern int max; 这样的整个语句整个都是多余的,
如果只删除extern关键字, 等于在函数体内重新定义了一个局部变量,。。这样的话,char longest[];这样的语句是不合法的。
学过变量的作用域(或生存期)没有?
sorry,之前没讲清楚。
2014-05-30 18:04
wenbao520
Rank: 1
等 级:新手上路
帖 子:1
专家分:5
注 册:2014-5-31
收藏
得分:5 
我不是专家,我不懂。我们多交流,754231619
2014-05-31 08:21
快速回复:<c 程序语言>第一章最后一段程序,编译报错
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.039837 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved