烦人的undefined reference to...

匚匚 2010-01-16 04:51:25
以下三个文件:zwlist.c为函数定义文件;zwlist.h是相应的头文件;temp.c是主程序文件。其中我将头文件放了stdio.h所在的目录之下。
执行以下操作:
gcc -c zwlist.c
ar cqs libt.a zwlist.o
gcc temp.c -static -L. -lt

出现以下提示,不明原因
temp.o:temp.c:<.text+0x1a>: undefined reference to `_initstack`
temp.o:temp.c:<.text+0xba>: undefined reference to `_push`
temp.o:temp.c:<.text+0x111>: undefined reference to `_pop`
temp.o:temp.c:<.text+0x172>: undefined reference to `_pop`
temp.o:temp.c:<.text+0x1e9>: undefined reference to `_pop`
temp.o:temp.c:<.text+0x260>: undefined reference to `_pop`
clooect2: ld returned 1 exit status



/* =====zwlist.h===== */

typedef int ElementType;
#ifndef ZW_STACK_ARRAY
#define ZW_STACK_ARRAY
#define Min_liary (6)
struct arraystack
{
ElementType min;
ElementType top;
ElementType *array;
};
typedef struct arraystack *stack_zw;

stack_zw initstack(int);
int push(stack_zw,ElementType);
ElementType pop(stack_zw); //
ElementType top(stack_zw); //
#endif

/* ==== zwlist.c ==== */

#include "zwlist.h"
#include "stdio.h"
#include "stdlib.h"

/*用数组实现栈*/
#ifndef ZW_STACK_ARRAY
#define ZW_STACK_ARRAY
stack_zw initstack(int n)//创建头结点及数组
{
stack_zw s;
n=n<Min_liary?Min_liary:n;
if((s=(stack_zw)malloc(sizeof(struct arraystack)))==NULL)
{
printf("未能成功创建头结点!\n");
return NULL;
}
s->min=n;
s->top=-1;
s->array=(ElementType *)malloc(n*sizeof(ElementType));
return s;
}
int push(stack_zw k,ElementType x)//入栈
{
if(k->top==k->min-1)
{
printf("数组已满\n");
return 0;
}
k->array[++k->top]=x;
return 1;
}
ElementType pop(stack_zw m)//出栈
{
if(m->top==-1)
{
printf("数组已空\n");
return 0;
}
return m->array[m->top--];
}
#endif //ZW_STACK_ARRAY

/* ===== temp.c ===== */

#include<time.h>
#include <stdio.h>
#include<stdlib.h>
#include "zwlist.h"

int main(void)
{
int card[52];
int pos;
int i,temp;
long temptime;
stack_zw s;
s=initstack(100);
srand(time(&temptime)%60);
for(i=0;i<52;i++)
card[i]=0;
i=0;
while(i!=52)
{
pos=rand()%52;
if(card[pos]==0)
{
push(s,pos);
card[pos]=1;
i++;
}
}
printf(" 1 2 3 4 \n");
printf(" ============================\n");
for(i=0;i<4;i++)
{
temp=pop(s);
printf(" [%c%2d] ",temp/13+3,temp%13+1);
temp=pop(s);
printf(" [%c%2d] ",temp/13+3,temp%13+1);
temp=pop(s);
printf(" [%c%2d] ",temp/13+3,temp%13+1);
temp=pop(s);
printf(" [%c%2d] ",temp/13+3,temp%13+1);
printf("\n");
}
}
...全文
1051 27 打赏 收藏 转发到动态 举报
写回复
用AI写文章
27 条回复
切换为时间正序
请发表友善的回复…
发表回复
arong1234 2010-01-17
  • 打赏
  • 举报
回复
对于C语言无法兼顾,一个结构的成员的类型必须固定,不可能既是int,也是float。因此你必须定义两套完全一样的结构,分别实现int和float
在C++中,你可以用模板。

这个帖子你问的太多了,我觉得这些基础的你还是去看书比较好
[Quote=引用 26 楼 zhw952 的回复:]
比如本贴开始中的内容:
struct arraystack
{
    ElementType min; 
    ElementType top; 
    ElementType *array;
};
  在一个文件中,有时要求ElementType 为int型 ,有时又要求为float型,如何做到兼顾?
[/Quote]
匚匚 2010-01-17
  • 打赏
  • 举报
回复
比如本贴开始中的内容:
struct arraystack
{
ElementType min;
ElementType top;
ElementType *array;
};
在一个文件中,有时要求ElementType 为int型 ,有时又要求为float型,如何做到兼顾?
arong1234 2010-01-17
  • 打赏
  • 举报
回复
那你应该另外起一个名字,一个类型代表完全不同的含义,是非常不合理的
[Quote=引用 22 楼 zhw952 的回复:]
如果在同一文件中,一个实际为int型,一个实际为float型呢?
[/Quote]
bladesoft 2010-01-17
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 zhw952 的回复:]
如果在同一文件中,一个实际为int型,一个实际为float型呢?
[/Quote]
一个方法.c文件里条件编译,另外一个方法.c文件里条件包含。只要逻辑清楚,都可以
匚匚 2010-01-17
  • 打赏
  • 举报
回复
再顶一下,看还有没有要讲的
匚匚 2010-01-16
  • 打赏
  • 举报
回复
如果在同一文件中,一个实际为int型,一个实际为float型呢?
arong1234 2010-01-16
  • 打赏
  • 举报
回复
如果改头文件,你只要改一处
如果改c,那么所有使用这个函数的.c都需要改
漏掉一个,你就完了
[Quote=引用 20 楼 zhw952 的回复:]
  我在头文件中定义的ElementType是int型 ,如果实际我要用的是float型,难道用前去改头文件?我觉得起码应将应文件中的typedef int ElementType改为#define ElementType int,方便在主程序中结束定义如,#ifdef ElementType
    #undef
    #define ElementType float
[/Quote]
匚匚 2010-01-16
  • 打赏
  • 举报
回复
我在头文件中定义的ElementType是int型 ,如果实际我要用的是float型,难道用前去改头文件?我觉得起码应将应文件中的typedef int ElementType改为#define ElementType int,方便在主程序中结束定义如,#ifdef ElementType
#undef
#define ElementType float
arong1234 2010-01-16
  • 打赏
  • 举报
回复
这样使用你zwlist的人就会发现他们所认为的element type和你在zwlist.c中实际不一样,这样逻辑就完全不对了。所以在.c中用的类型必须和.h中完全一致,这样类型应该方在头文件中定义才对,除非这个类型只是这个c自己用,别人不用
[Quote=引用 18 楼 zhw952 的回复:]
比如说我前面的zwlist.h中的typedef int ElementType; 是不是应在头文件中删除,而在主程序中加一句#define ElementType int;这样的话,在同一主程序中当主函数要调用该头文件中声明的另一个含ElementType类型的函数时,就可以先结束定义,再重新定义
[/Quote]
匚匚 2010-01-16
  • 打赏
  • 举报
回复
比如说我前面的zwlist.h中的typedef int ElementType; 是不是应在头文件中删除,而在主程序中加一句#define ElementType int;这样的话,在同一主程序中当主函数要调用该头文件中声明的另一个含ElementType类型的函数时,就可以先结束定义,再重新定义
arong1234 2010-01-16
  • 打赏
  • 举报
回复
我觉得你应该先把我给你那篇文章看完,了解guard macro这种条件编译宏的用处

一般而言,在函数定义中使用条件编译,可以使得函数在不同编译条件、不同操作系统中函数都可以正确工作。例如我有一个库,在amd机器上应该用函数fooamd,在32位,x64上的函数分别是foo32, foox64,那么一个使用这个库的函数可能就是这样定义:


void bar()
{

#ifdef PLATFORM_AMD64
fooamd();
#elif PLATFORM_I386
foo32();
#elif PLATFORM_X64
foox64();
#else
#error "you must define platform"
#endif
}


[Quote=引用 16 楼 zhw952 的回复:]
  能否详细说说
[/Quote]
匚匚 2010-01-16
  • 打赏
  • 举报
回复
能否详细说说
arong1234 2010-01-16
  • 打赏
  • 举报
回复
是否需要条件编译,是根据你功能需求来决定的
[Quote=引用 14 楼 zhw952 的回复:]
  再问一下高人:在函数定义时是否有必要也设置条件编译。比如在队列的函数定义文件中,有循环数组实现的队列,也有链表实现的队列,这样有必要分别设置条件编译吗
引用 12 楼 arong1234 的回复:
这是下面的guard macro用错所致!
#ifndef ZW_STACK_ARRAY
#define ZW_STACK_ARRAY
由于zwlist.h中这个宏已经被定义,当你在zwlist.c包含zwlist.h之后,
#ifndef ZW_STACK_ARRAY已经不成立,所有的zwlist.c中的代码都被直接忽略

楼主看看这个:

http://blog.vckbase.com/arong/archive/2004/05/28/294.aspx

[/Quote]
匚匚 2010-01-16
  • 打赏
  • 举报
回复
再问一下高人:在函数定义时是否有必要也设置条件编译。比如在队列的函数定义文件中,有循环数组实现的队列,也有链表实现的队列,这样有必要分别设置条件编译吗
[Quote=引用 12 楼 arong1234 的回复:]
这是下面的guard macro用错所致!
#ifndef ZW_STACK_ARRAY
#define ZW_STACK_ARRAY
由于zwlist.h中这个宏已经被定义,当你在zwlist.c包含zwlist.h之后,
#ifndef ZW_STACK_ARRAY已经不成立,所有的zwlist.c中的代码都被直接忽略

楼主看看这个:

http://blog.vckbase.com/arong/archive/2004/05/28/294.aspx
[/Quote]
匚匚 2010-01-16
  • 打赏
  • 举报
回复
高人啊!谢谢高人的精彩回复,问题解决了,一针见血!


[Quote=引用 12 楼 arong1234 的回复:]
这是下面的guard macro用错所致!
#ifndef ZW_STACK_ARRAY
#define ZW_STACK_ARRAY
由于zwlist.h中这个宏已经被定义,当你在zwlist.c包含zwlist.h之后,
#ifndef ZW_STACK_ARRAY已经不成立,所有的zwlist.c中的代码都被直接忽略

楼主看看这个:

http://blog.vckbase.com/arong/archive/2004/05/28/294.aspx
[/Quote]
arong1234 2010-01-16
  • 打赏
  • 举报
回复
这是下面的guard macro用错所致!
#ifndef ZW_STACK_ARRAY
#define ZW_STACK_ARRAY
由于zwlist.h中这个宏已经被定义,当你在zwlist.c包含zwlist.h之后,
#ifndef ZW_STACK_ARRAY已经不成立,所有的zwlist.c中的代码都被直接忽略

楼主看看这个:

http://blog.vckbase.com/arong/archive/2004/05/28/294.aspx
cattycat 2010-01-16
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 hairetz 的回复:]
zwlist.h跟temp.c放在同一个文件夹下即可。
[/Quote]
然后gcc temp.c 应该行。
jackyjkchen 2010-01-16
  • 打赏
  • 举报
回复
在C文件的路径里执行gcc呢?
匚匚 2010-01-16
  • 打赏
  • 举报
回复
我正是这样做的,gcc temp.c -static -L. -lt
[Quote=引用 7 楼 arong1234 的回复:]
-L只说明在哪些目录找库,并不真正把库链接起来
你还需要用下面开关连库
-lmylib

mylib换成你自己的库名字

[/Quote]
flyyyri 2010-01-16
  • 打赏
  • 举报
回复
budong
加载更多回复(7)

69,372

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧