这么讲函数声明写到一个c 头文件声明函数

c语言中一个函数的声明和定义有区别吗? - 知乎有问题,上知乎。知乎作为中文互联网最大的知识分享平台,以「知识连接一切」为愿景,致力于构建一个人人都可以便捷接入的知识分享网络,让人们便捷地与世界分享知识、经验和见解,发现更大的世界。46被浏览<strong class="NumberBoard-itemValue" title="分享邀请回答9添加评论分享收藏感谢收起2添加评论分享收藏感谢收起C语言怎样将定义的函数中程序运行的结果写到文件中_百度知道
C语言怎样将定义的函数中程序运行的结果写到文件中
我用的是链表编写的学生信息,插入,然后删除,最后还要定义一个file的自定义函数,把屏幕上打印的学生信息保存到d盘中,可是我只会以二进制写
#include&stdio.h&
#include&stdlib.h&
#include&malloc.h&
struct student
char name[20];
我有更好的答案
#include&stdio.h&#include&stdlib.h&#include&malloc.h&struct student{
char name[20];
struct student*}; struct student* creat(){
struct student* phead=NULL;
struct student* ptail,*p;
ptail=p=(struct student*)malloc(sizeof(struct student));
printf(&依次输入学生学号,姓名,成绩:&#92;n&);
scanf(&%d%s%f&,&p-&num,p-&name,&p-&score);
while(p-&num!=10)
if(count&=10)
p-&pnext=NULL;
ptail-&pnext=p;
p=(struct student*)malloc(sizeof(struct student));
scanf(&%d%s%f&,&p-&num,p-&name,&p-&score);
free(p);} void print(struct student* phead){
struct student *
int index=1;
printf(&--这个链表中有%d个学生--&#92;n&,count);
printf(&&#92;n&);
while(ptemp!=NULL)
printf(&学生%d是:
printf(&学号%d
&,ptemp-&num);
printf(&姓名%s
&,ptemp-&name);
printf(&成绩%f
&#92;n&,ptemp-&score);
printf(&&#92;n&);
ptemp=ptemp-&
}} struct student* insert(struct student* phead){
struct student*
printf(&插入一个成员&#92;n&);
p=(struct student*)malloc(sizeof(struct student));
scanf(&%d%s%f&,&p-&num,p-&name,&p-&score);
count++;} void delet (struct student* phead,int index)//把delete改成了delet,其他没变,否则我的系统编译出错。{
struct student*
struct student*
printf(&删除第%d个学生&#92;n&,index);
for(i=1;i&i++)
ptemp=ptemp-&
ppre-&pnext=ptemp-&
free(ptemp);
count--;} void file(struct student* phead){
if((fp=fopen(&D:&#92;&#92;cx.txt&,&wb&))==NULL)
{printf(&file can not open!&#92;n&); exit(1);}
int index=1;//加上这一句
while(phead!=NULL)
//fwrite(phead,sizeof(struct student),1,fp);//屏蔽这一句
//加上下面这几句
fprintf(fp,&学生%d是:
fprintf(fp,&学号%d
&,phead-&num);
fprintf(fp,&姓名%s
&,phead-&name);
fprintf(fp,&成绩%f
&#92;n&,phead-&score);
fprintf(fp,&&#92;n&);
index++;//ok
phead=phead-& }
fclose(fp);
printf(&-----成功保存信息!-----&#92;n&);
} int main(){
struct student*
phead=creat();
phead=insert(phead);
delet(phead,2);
print(phead);
file(phead);
return 0;}试试看可以文本打印没?,一个小提醒:你的程序运行似乎有点小问题,自己看看吧改成下面可能容错性会好一点,也试试:(我也初学,请见谅!)#include&stdio.h&#include&stdlib.h&#include&malloc.h&typedef struct Student//这里我用了首字母大写{
char name[20];
struct Student *//这里如果把struct Student改成student会编译出错(以前没注意)}//利用typedef后面可以省力点 student * creat(){
student * phead=NULL;
student * ptail, *
ptail=p=(student *)malloc(sizeof(student));
printf(&依次输入学生学号,姓名,成绩:&#92;n&);
scanf(&%d%s%f&,&p-&num,p-&name,&p-&score);
while(p-&num!=0)//这里我改了,容错性会好些,输入学号为0时会结束输入,
//后面程序也考虑了空记录的情况
if(count==1)//第一条记录为头记录phead=p;//设置第一条记录为头记录
elseptail-&pnext=p;
p=(student*)malloc(sizeof(student));
scanf(&%d%s%f&,&p-&num,p-&name,&p-&score);
ptail-&pnext=NULL;//设置尾记录指向空地址} void print(student* phead){
student *ptemp=
int index=1;
printf(&--这个链表中有%d个学生--&#92;n&,count);
printf(&&#92;n&);if (phead!=NULL)//判断是不是为空记录{do{printf(&学生%d是:
&,index);printf(&学号%d
&,ptemp-&num);printf(&姓名%s
&,ptemp-&name);printf(&成绩%f
&#92;n&,ptemp-&score);printf(&&#92;n&);ptemp=ptemp-&index++;}while(ptemp!=NULL);//看看不用do...while换成while行不?有时会搞不明白的,呵呵}} student* insert(student* phead)//插入函数未改动,但该函数是插到第一个之前的,可以改一下{
printf(&插入一个成员&#92;n&);
p=(student*)malloc(sizeof(student));
scanf(&%d%s%f&,&p-&num,p-&name,&p-&score);
count++;} student* delet (student* phead,int index)//我把delete改成delet了否则我的编译器没法通过{
printf(&删除第%d个学生&#92;n&,index);
if(index&count || index&=0)//提高了容错性printf(&共有%d个记录,无法删除第%d个学生&#92;n&,count,index);else{if (1==index){phead=phead-&}else{for(i=1;i&i++){ppre=ptemp=ptemp-&}
ppre-&pnext=ptemp-&}free(ptemp);
count--;}} void file(student* phead){
if((fp=fopen(&D:&#92;&#92;cx.txt&,&wb&))==NULL)
{printf(&file can not open!&#92;n&); exit(1);}
int index=1;
fprintf(fp,&--这个链表中有%d个学生--&#92;n&,count);
fprintf(fp,&&#92;n&);
if (ptemp!=NULL){do{fprintf(fp,&学生%d是:
&,index);fprintf(fp,&学号%d
&,ptemp-&num);fprintf(fp,&姓名%s
&,ptemp-&name);fprintf(fp,&成绩%f
&#92;n&,ptemp-&score);fprintf(fp,&&#92;n&);ptemp=ptemp-&index++;}while(ptemp!=NULL);}fclose(fp);printf(&-----成功保存信息!-----&#92;n&);} int main(){
phead=creat();
phead=insert(phead);
phead=delet(phead,2);//分别改成0,1,2,末记录,试试原来的程序这里有问题的
print(phead);
file(phead);
return 0;}
采纳率:73%
使用“w”打开文件,把结构体中的属性一项一项写入文件。比如 fputs(stu-&name, fp) 就可以把结构体中学生姓名一项以文本格式写入文件。
为您推荐:
其他类似问题
程序运行的相关知识
&#xe675;换一换
回答问题,赢新手礼包&#xe6b9;
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。板函数的定义和声明须在同一文件内
按照C++中代码的惯例,类声明在h文件中,类定义在cpp文件中,相应的成员函数声明也在h文件中,定义在cpp文件中。但是如果这样的架构用在模板函数中,在调用模板函数的地方链接器便会报错,error LNK2001: unresolved external symbol。将定义写在与声明相同的文件中问题解决,解释如下:
“大部分编译器在编译模板时都使用包含模式。也就是一般使用的把模板放到头文件中再包含。
当你不使用这个模版函数或模版类,编译器并不实例化它。当你使用时,编译器需要实例化它。因为编译器是一次只能处理一个编译单元,也就是一次处理一个cpp文件,所以实例化时需要看到该模板的完整定义,所以都放在头文件中。
这不同于普通的函数,在使用普通的函数时,编译时只需看到该函数的声明即可编译,而在链接时由链接器来确定该函数的实体。”
void fun(T);
#include "temp.h"
void fun(T){}
#include "temp.h"
void main()
由于main.cpp用到了fun(a),所以在编译main.cpp的时候,编译器知道它要用int来实例化fun(T)中的T,也就是要实例化fun(int),而要实例化一个函数模板就必须要知道这个函数模板的定义,但是由于main.cpp和包含函数模板定义的temp.cpp是分开编译的,所以编译器在编译main.cpp的时候就不能够用int来实例化fun(T),这样编译器就只能够把fun&int&(a)当成一个外部符号,交由linker来resolve。
另外编译器在编译temp.cpp的时候,同样因为temp.cpp和main.cpp是分开编译的,所以此时编译器并不知道main.cpp中用到了fun&int&(a),所以此时编译器虽然知道函数模板的定义,但也不会去实例化任何fun,当然就不会用int来实例化fun&T&了。
结果就是,你在main.obj引用了外部符号fun&int&,但是在temp.obj中不存在fun&int&,所以linker就会报告无法解析的外部符号了。"
没有更多推荐了,
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!C语言,我写了三个文件一个mymath.c写了函数定义,一个mymath.h写了声明,还有一个主文_百度知道
C语言,我写了三个文件一个mymath.c写了函数定义,一个mymath.h写了声明,还有一个主文
C语言,我写了三个文件一个mymath.c写了函数定义,一个mymath.h写了声明,还有一个主文C语言,我写了三个文件一个mymath.c写了函数定义,一个mymath.h写了声明,还有一个主文件,在主文件里包含了mymath.h,但.h不是只有声明吗?怎么找到的函数定义
我有更好的答案
程序编译的时候,并不会去找b.cpp文件中的函数实现,只有在link的时候才进行这个工作。我们在b.cpp或c.cpp中用#include &a.h&实际上是引入相关声明,使得编译可以通过,程序并不关心实现是在哪里,是怎么实现的。源文件编译后成生了目标文件(.o或.obj文件),目标文件中,这些函数和变量就视作一个个符号。在link的时候,需要在makefile里面说明需要连接哪个.o或.obj文件(在这里是b.cpp生成的.o或.obj文件),此时,连接器会去这个.o或.obj文件中找在b.cpp中实现的函数,再把他们build到makefile中指定的那个可以执行文件中。
哥你说的呢个 makefile 是系统自动生成的吗?我刚学c链接的时候,他是自动在项目文件中找包含定义的.c文件编译成的.obj文件吗?我用的VS2015
编译程序只在main函数调用你的函数时知道调用规则即可,根本不关心函数的具体内容。函数具体是否存在是连接程序管的,如果函数没有写,会报错说该函数没有提供obj文件。
本回答被网友采纳
编译器可以找到 的~~~~~~~~~~~
为您推荐:
其他类似问题
&#xe675;换一换
回答问题,赢新手礼包&#xe6b9;
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。原文:http://www.cnblogs.com/ider/archive//what_is_in_cpp_header_and_implementation_file.html
在C++编程过程中,随着项目的越来越大,代码也会越来越多,并且难以管理和分析。于是,在C++中就要分出了头(.h)文件和实现(.cpp)文件,并且也有了Package的概念。
对于以C起步,C#作为&母语&的我刚开始跟着学习C++对这方面还是感到很模糊。虽然我可以以C的知识面对C++的语法规范,用C#的思想领悟C++中类的使用。但是C#中定义和实现是都在一个文件中(其实都是在类里面),而使用C的时候也只是编程的刚刚起步,所写的程序也只要一个文件就够了。因此对于C++的Package理解以及.h文件和.cpp文件的总是心存纠结。
幸好有详细的让我了解,一次对于Package的认识就明白多了。简单讲,一个Package就是由同名的.h和.cpp文件组成。当然可以少其中任意一个文件:只有.h文件的Package可以是接口或模板(template)的定义;只有.cpp文件的Package可以是一个程序的入口。
当然更具体详细的讲解,欢迎下载导师的教学来了解更多。
不过我在这里想讲的还是关于.h文件和.cpp文件
知道Package只是相对比较宏观的理解:我们在项目中以Package为编辑对象来扩展和修正我们的程序。编写代码时具体到应该把什么放到.h文件,又该什么放在.cpp文件中,我又迷惑了。
虽然Google给了我很多的链接,但是大部分的解释都太笼统了:申明写在.h文件,定义实现写在.cpp文件。这个解释没有差错,但是真正下手起来,又会发现不知道该把代码往哪里打。
于是我又把这个问题抛给了,他很耐心地给我详详细细地表述了如何在C++中进行代码分离。很可惜,第一次我听下了,但是没有听太懂,而且本来对C++就了解不深,所以也没有深刻的印象。
经过几个项目的试炼和体验之后,我又拿出这个问题问,他又一次耐心地给我讲解了一遍(我发誓他绝对不是忘记了我曾经问过同样的问题),这次我把它记录了下来。
为了不再忘记,我将它们总结在这里。
全局变量申明(带extern限定符)
全局函数的申明
带的全局函数的定义&
带的全局模板函数的申明和定义
类函数成员和数据成员的申明(在类内部)
类定义内的函数定义(相当于inline)
带的数据成员在类内部的初始化
带的类定义外的函数定义
模板类的定义
模板类成员的申明和定义(定义可以放在类内或者类外,类外不需要写inline)
实现文件(.cpp)
全局变量的定义(及初始化)
全局函数的定义&
& & & & & & & & & & & & & (无)&
类函数成员的定义
类带static限定符的数据成员的初始化
*申明:declaration*定义:definition
头文件的所有内容,都必须包含在
#ifndef&{Filename}&#define&{Filename}&//{Content of head file}&#endif
这样才能保证头文件被多个其他文件引用(include)时,内部的数据不会被多次定义而造成错误
inline限定符
在头文件中,可以对函数用inline限定符来告知编译器,这段函数非常的简单,可以直接嵌入到调用定义之处。
当然inline的函数并不一定会被编译器作为inline来实现,如果函数过于复杂,编译器也会拒绝inline。
因此简单说来,代码最好短到只有3-5行的才作为inline。有循环,分支,递归的函数都不要用做inline。
对于在类定义内定义实现的函数,编译器自动当做有inline请求(也是不一定inline的)。因此在下边,我把带有inline限定符的函数成员和写在类定义体内的函数成员统称为&要inline的函数成员&
非模板类型
就像前面笼统的话讲的:申明写在.h文件。
对于函数来讲,没有实现体的函数,就相当于是申明;而对于数据类型(包括基本类型和自定义类型)来说,其申明就需要用extern来修饰。
然后在.cpp文件里定义、实现或初始化这些全局函数和全局变量。
不过导师一直反复强调:不许使用全局函数和全局变量。用了之后造成的后果,目前就是交上去的作业项目会扣分。当然不能用自有不能用的理由以及解决方案,不过不在目前的讨论范围内。
自定义类型
对于自定义类型,包括类(class)和结构体(struct),它们的定义都是放在.h文件中。其成员的申明和定义就比较复杂了,不过看上边的表格,还是比较清晰的。
函数成员无论是否带有static限定符,其申明都放在.h文件的类定义内部。
对于要inline的函数成员其定义放在.h文件;其他函数的实现都放在.cpp文件中。
数据成员的申明与定义都是放在.h文件的类定义内部。对于数据类型,关键问题是其初始化要放在什么地方进行。
对于只含有static限定符的数据成员,它的初始化要放在.cpp文件中。因为它是所有类对象共有的,因此必须对它做合适的初始化。
对于只含有const限定符的数据成员,它的初始化只能在构造函数的初始化列表中完成。因为它是一经初始化就不能重新赋值,因此它也必须进行合适的初始化。
对于既含有static限定符,又含有const限定符的数据成员,它的初始化和定义同时进行。它也是必须进行合适的初始化
对于既没有static限定符,又没有const限定符的数据成员,它的值只针对本对象可以随意修改,因此我们并不在意它的初始化什么时候进行。
C++中,模板是一把开发利器,它与C#,Java的泛型很相似,却又不尽相同。以前,我一直只觉得像泛型,模板这种东西我可能一辈子也不可能需要使用到。但是在导师的强制逼迫使用下,我才真正体会到模板的强大,也真正知道要如何去使用模板,更进一步是如何去设计模板。不过这不是三言两语可以讲完的,就不多说了。
对于模板,最重要的一点,就是在定义它的时候,编译器并不会对它进行编译,因为它没有一个实体可用。
只有模板被具体化(specialization)之后(用在特定的类型上),编译器才会根据具体的类型对模板进行编译。
所以才定义模板的时候,会发现编译器基本不会报错(我当时还很开心的:我写代码尽然会没有错误,一气呵成),也做不出智能提示。但是当它被具体用在一个类上之后,错误就会大片大片的出现,却往往无法准确定位。
因此设计模板就有设计模板的一套思路和方式,但是这跟本文的主题也有偏。
因为模板的这种特殊性,它并没有自己的准确定义,因此我们不能把它放在.cpp文件中,而要把他们全部放在.h文件中进行书写。这也是为了在模板具体化的时候,能够让编译器可以找到模板的所有定义在哪里,以便真正的定义方法。
至于模板类函数成员的定义放在哪里,导师的意见是放在类定义之外,因为这样当你看类的时候,一目了然地知道有那些方法和数据;我在用Visual Studio的时候查看到其标准库的实现,都是放在类内部的。
可能是我习惯了C#的风格,我比较喜欢把它们都写在类内部,也因为在开发过程中,所使用的编辑器都有一个强大的功能:代码折叠。
当然还有其他原因就是写在类外部,对于每一个函数成员的实现都需要把模板类型作为限定符写一遍,把类名限定符也要写一遍。
=========================================================================================================
谢 邀,这个问题让我想起我在实习的时候犯的一个错误,就是把模版类的定义和实现分开写了,结果编译出错,查了两天才查出问题。C++中每一个对象所占用的空间大小,是在编译的时候就确定的,在模板类没有真正的被使用之前,编译器是无法知道,模板类中使用模板类型的对象的所占用的空间的大小的。只有模板被真正使用的时候,编译器才知道,模板套用的是什么类型,应该分配多少空间。这也就是模板类为什么只是称之为模板,而不是泛型的缘故。既然是在编译的时候,根据套用的不同类型进行编译,那么,套用不同类型的模板类实际上就是两个不同的类型,也就是说,stack&int&和stack&char&是两个不同的数据类型,他们共同的成员函数也不是同一个函数,只不过具有相似的功能罢了。如上图所示,很简短的六行代码,用的是STL里面的stack,stack&int&和stack&char&的默认构造函数和push函数的入口地址是不一样的,而不同的stack&int&对象相同的函数入口地址是一样的,这个也反映了模板类在套用不同类型以后,会被编译出不同代码的现象。所以模板类的实现,脱离具体的使用,是无法单独的编译的;把声明和实现分开的做法也是不可取的,必须把实现全部写在头文件里面。为了清晰,实现可以不写在class后面的花括号里面,可以写在class的外面。
================================
还是把头文件的内容都放在#ifndef和#endif中吧。不管你的头文件会不会被多个文件引用,你都要加上这个。一般格式是这样的:
#ifndef &标识&&#define &标识&
......&......
&标识&在理论上来说可以是自由命名的,但每个头文件的这个&标识&都应该是唯一的。标识的命名规则一般是头文件名全大写,前后加下划线,并把文件名中的&.&也变成下划线,如:stdio.h
#ifndef _STDIO_H_&#define _STDIO_H_
2.在#ifndef中定义变量出现的问题(一般不定义在#ifndef中)。
#ifndef AAA#define AAA...&&&& ...#endif里面有一个变量定义在vc中链接时就出现了i重复定义的错误,而在c中成功编译。
(1).当你第一个使用这个头的.cpp文件生成.obj的时候,int i 在里面定义了当另外一个使用这个的.cpp再次[单独]生成.obj的时候,int i 又被定义然后两个obj被另外一个.cpp也include 这个头的,连接在一起,就会出现重复定义.
(2).把源程序文件扩展名改成.c后,VC按照C语言的语法对源程序进行编译,而不是C++。在C语言中,若是遇到多个int i,则自动认为其中一个是定义,其他的是声明。
(3).C语言和C++语言连接结果不同,可能(猜测)时在进行编译的时候,C++语言将全局变量默认为强符号,所以连接出错。C语言则依照是否初始化进行强弱的判断的。(参考)
解决方法:
(1).把源程序文件扩展名改成.c。
(2).推荐解决方案:.h中只声明在.cpp中定义
&x.h&#ifndef __X_H__#define __X_H__#endif //__X_H__&x.c&
阅读(...) 评论()

我要回帖

更多关于 易语言写到文件 的文章

 

随机推荐