C语言、C++:关于多文件编程

C语言、C++:关于多文件编程,第1张

你如果是用编译器自动生成的文件,编译器自动加到项目里,自己写的,你要手动在项目中添加文件,编译器才会检索,编译器只检索属于项目的文件
1,c或者cpp不需要包含,如果你是用VS系列,h和cpp是一对的,你包含了Xh就是能使用Xcpp的资源、你自己想包含的话那也无所谓,一般是编译器做的
2 h可以添加实现,一切都可以添加。但是为了代码的隐藏和符合编程的机制,一般都放到对应的cpp。简短的函数可以直接放在h,你自己找起来也方便
3包含了h就能直接使用对应的C。项目中这种事情一般让编译器去实现。其实编译的时候,编译器会自动检索所有文件,只要你有声明,实现不管你写在哪,编译器都会找到的,写在对应的h和cpp是为了方便和规范的需要

C++编程入门系列之二十四(C++程序设计必知:多文件结构和编译预处理命令)分类标签: C++ 编程入门 -
鸡啄米上一讲给大家讲了常引用、常对象和对象的常成员,今天给大家讲下编程入门知识--多文件结构和编译预处理命令。
一C++程序的多文件结构
之前鸡啄米给大家看了很多比较完整的C++程序的例子,大家可能发现了,它们的结构基本上可以分为三个部分:类的声明、类的成员函数的实现和主函数。因为代码比较少,所以可以把它们写在一个文件中,但是我们实际进行软件开发时,程序会比较复杂,代码量比较大,
一个程序按结构至少可以划分为三个文件:类的声明文件(h文件)、类的实现文件(cpp文件)和主函数文件(使用到类的文件),如果程序更复杂,我们会为每个类单独建一个声明文件和一个实现文件。这样我们要修改某个类时就直接找到它的文件修改即可,不需要其他的文件改动。
鸡啄米在第十九讲中讲生存期时有个时钟类的例子,现在鸡啄米给大家看下将那个程序按照上面说的结构分到三个文件里:
// 文件1:Clock类的声明,可以起名为Clockh
#include <iostream>
using namespace std;
class Clock //时钟类声明
{
public: //外部接口
Clock();
void SetTime(int NewH, int NewM, int NewS); //三个形参均具有函数原型作用域
void ShowTime();
~Clock(){}
private: //私有数据成员
int Hour,Minute,Second;
};
// 文件2:Clock类的实现,可以起名为Clockcpp
#include "Clockh"
//时钟类成员函数实现
Clock::Clock() //构造函数
{
Hour=0;
Minute=0;
Second=0;
}
void Clock::SetTime(int NewH,int NewM,int NewS)
{
Hour=NewH;
Minute=NewM;
Second=NewS;
}
void Clock::ShowTime()
{
cout<<Hour<<":"<<Minute<<":"<<Second<<endl;
}
// 文件3:主函数,可以起名为maincpp
#include "Clockh"
//声明全局对象g_Clock,具有文件作用域,静态生存期
Clock g_Clock;
int main() //主函数
{
cout<<"文件作用域的时钟类对象:"<<endl;
//引用具有文件作用域的对象:
g_ClockShowTime();
g_ClockSetTime(10,20,30);

Clock myClock(g_Clock); //声明具有块作用域的对象myClock,并通过默认拷贝构造函数用g_Clock初始化myClock
cout<<"块作用域的时钟类对象:"<<endl;
myClockShowTime(); //引用具有块作用域的对象
}
在vs2010中如何生成这三个文件呢?我们可以点菜单中Project->Add Class,在d出的对话框中选择c++ class,然后由d出个对话框,在class name处填上类名点finish就可以了,这样h文件和cpp文件会自动生成,我们也可以点Project->Add New Item,在d出的对话框中选择Header File(h)或C++ File(cpp)来生成h文件或cpp文件。
Clockcpp和maincpp都使用#include "Clockh"把类Clock的头文件Clockh包含进来。#include指令的作用就是将#include后面的文件嵌入到当前源文件该点处,被嵌入的文件可以是h文件也可以是cpp文件。如果不包含Clockh,Clockcpp和maincpp就不知道Clock类的声明形式,就无法使用此类,所以所有使用此类的文件都应该包含声明它的头文件。关于#include指令下面鸡啄米会讲。
上面的程序在编译时,由Clockcpp和Clockh编译生成Clockobj,由maincpp和Clockh编译生成mainobj,然后就是链接过程,Clockobj和mainobj链接生成mainexe可执行文件。如果我们只修改了类的实现文件,那么只需重新编译Clockcpp并链接就可以,别的文件不用管,这样就提高了效率。在Windows系统中的C++程序用工程来管理多文件结构,而Unix系统一般用make工具管理,如果大家从事Unix系统软件开发,就需要自己写make文件。
二编译预处理程序
编译器在编译源程序以前,要由预处理程序对源程序文件进行预处理。预处理程序提供了一些编译预处理指令和预处理 *** 作符。预处理指令都要由“#”开头,每个预处理指令必须单独占一行,而且不能用分号结束,可以出现在程序文件中的任何位置。
1#include指令
#include指令也叫文件包含指令,用来将另一个源文件的内容嵌入到当前源文件该点处。其实我们一般就用此指令来包含头文件。#include指令有两种写法:
#include <文件名>
使用这种写法时,会在C++安装目录的include子目录下寻找<>中标明的文件,通常叫做按标准方式搜索。
#include "文件名"
使用这种写法时,会先在当前目录也就是当前工程的目录中寻找""中标明的文件,若没有找到,则按标准方式搜索。
2#define和#undef指令
如果你学过C语言,就会知道用#define可以定义符号常量,比如,#define PI 314 这条指令定义了一个符号常量PI,它的值是314。C++也可以这样定义符号常量,但一般更常用的是在声明时用const关键字修饰。C语言还用#define定义参数宏,来实现简单的函数运算,比如,#define add(x,y) (x+y) 这条指令说明如果我们用到add(1,2)则预处理后就会用(1+2)代替,C++中一般用内联函数来实现。
#undef用来删除由#define定义的宏,使其不再起作用。
3条件编译指令
用条件编译指令可以实现某些代码在满足一定条件时才会参与编译,这样我们可以利用条件编译指令将同一个程序在不同的编译条件下生成不同的目标代码。例如,我们可以在调试程序时加入一些调试语句,用条件编译指令控制只有在debug模式下这些调试语句才参与编译,而在release模式下不参与编译。
条件编译指令有5中形式:
a第一种形式:
#if 常量表达式
程序正文 //当“ 常量表达式”非零时本程序段参与编译
#endif
b第二种形式:
#if 常量表达式
程序正文1 //当“ 常量表达式”非零时本程序段参与编译
#else
程序正文2 //当“ 常量表达式”为零时本程序段参与编译
#endif
c第三种形式:
#if 常量表达式1
程序正文1 //当“ 常量表达式1”非零时本程序段参与编译
elif 常量表达式2
程序正文2 //当“常量表达式1”为零、“ 常量表达式2”非零时本程序段参与编译

elif 常量表达式n
程序正文n //当“常量表达式1”、、“常量表达式n-1”均为零、“ 常量表达式n”非零时本程序段参与编译
#else
程序正文n+1 //其他情况下本程序段参与编译
#endif
d第四种形式:
#ifdef 标识符
程序段1
#else
程序段2
#endif
如果“标识符”经#defined定义过,且未经undef删除,则编译程序段1,否则编译程序段2。
e第五种形式:
#ifndef 标识符
程序段1
#else
程序段2
#endif
如果“标识符”未被定义过,则编译程序段1,否则编译程序段2。
4define *** 作符
define是预处理 *** 作符,不是指令,所以不能用#开头。使用形式为:define(标识符)。如果括号里的标识符用#define定义过,并且没有用#undef删除,则define(标识符)为非0,否则为0。可以这样使用:
#if !define(HEAD_H)
#define HEAD_H
我们在包含头文件时,有时多次重复包含同一个头文件,比如下面这种情况:
// maincpp文件
#include "file1h"
#include "file2h"
int main()
{

}
// file1h文件
#include "headh"

// file2h文件
#include "headh"

// headh文件

class A
{

}

maincpp包含了file1h文件,file1h又包含了headh文件,maincpp还包含了file2h文件,file2h也包含了headh文件,那么maincpp就包含了两次headh文件,在编译时就会报错,说headh中的类A重复定义了。这时我们可以在被重复包含的文件headh中使用条件编译指令,用一个唯一的标识符来标识headh文件是否已经编译过,如果已经编译过则不会重复编译了。鸡啄米给大家改写下上面的headh文件:
// headh文件
#ifndef HEAD_H
#define HEAD_H

class A
{

}

#endif
在这个改好的headh文件中,上来会先判断HEAD_H是否被定义过,如果没有被定义过,则headh文件还没参与过编译,就编译此文件中的源代码,同时定义HEAD_H,标记headh文件已经参与过编译。如果HEAD_H已经被定义过,则说明此文件已经参与过编译,编译器会跳过本文件左右内容编译其他部分,类A也不会有重复定义的错误了。

c的话,没有类,就没有接口,相对c++简单一点。
我说说我的见解吧
首先是头文件,声明你写的函数。注意头文件加如下代码,防止重复包含
#ifndef MYHEAD_H
#define MYHEAD_H

#endif
MYHEAD_H是你的文件名,自己改,省略号是你声明的函数,以及变量
然后就是你写的函数的实现了。如果一个c里面写不完,可以分做功能相似的几个c源文件。
最后main函数肯定一个c文件,包含自己写的头文件。
最后,如果只是练习性的小程序可以不用深究,做项目的时候才必须分多个文件,你是写来给别人看到,头文件就是声明,源文件是实现。某些时候不能给别人提供源码,就吧c编译成dll等。
h c c(main),3个文件ok

//文件Ah
class CInterface;
class CA
{
public:
CA(CInterface pinterface)
{
m_pInterface = pinterface;
}
void fun_a()
{
printf("fun_a\r\n");
}
CInterface m_pInterface;
};
//文件Bh
class CInterface;
class CB
{
public:
CB(CInterface pinterface)
{
m_pInterface = pinterface;
}
CInterface m_pInterface;
};
//文件Ch
class CInterface;
class CC
{
public:
CC(CInterface pinterface)
{
m_pInterface = pinterface;
}
CInterface m_pInterface;
};
//接口文件类
class CA;
class CB;
class CC;
class CInterface
{
public:
void create_obj()
{
m_pa = new CA(this);
m_pb = new CB(this);
m_pc = new CC(this);
}
CA get_a()
{
return m_pa;
}
CB get_b()
{
return m_pb;
}
CC get_c()
{
return m_pc;
}
private:
CA m_pa;
CB m_pb;
CC m_pc;
};
int main()
{
CInterface test;
testcreate_obj();
//文件c调用文件a的过程
//通过这种方法,可以访问所有文件,且实现分离
testget_c()->m_pInterface->get_a()->fun_a();
return 0;
}

上了大学有很多同学都在学习C语言,C++就是C语言的一种,那么怎么用c语言写一个简单的程序hello world呢,下边来给大家演示一下

工具/材料

电脑,c语言软件

鼠标左键双击c语言软件,打开,打开后界面如图,点击关闭即可

点击上方程序窗口左上角的文件,选择新建

在打开的窗口中选择文件,下边一般是第四个 c++Source file,输入文件名(hellwc),一定要以“c”为后缀结尾

进入编辑页面在,页面编辑源代码就可以

#include<stdioh>

void main()

{

printf("hello world!"n);

}
然后选择保存,打印,输出运行。

输出的效果就是这样了,一个简单的c语言程序就写好了

特别提示

所有的输入都要在英文半角的情况下输入,不然程序会不能识别,会报错。


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/13332894.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-07-16
下一篇 2023-07-16

发表评论

登录后才能评论

评论列表(0条)

保存