C语言中预定义宏的应用

      __LINE__                       在源代码中插入当前源代码行号  
      __FILE__                       在源代码中插入当前源代码文件名  
      __FUNCTION__(__fucn__)         在源代码中插入当前源代码函数名
      __DATE__                       在源代码中插入当前编译日期〔注意和当前系统日期区别开来〕  
      __TIME__                       在源代码中插入当前编译时间〔注意和当前系统时间区别开来〕        
      __STDC__                       当要求程序严格遵循ANSIC标准时该标识符被赋值为1。  
      __cplusplus  
  标识符__LINE__,__FILE__,__func__通常用来调试程序;  

  标识符__DATE__和__TIME__通常用来在编译后的程序中加入一个时间标志,以区分程序的不同版本;

  当要求程序严格遵循ANSIC标准时,标识符__STDC__就会被赋值为1;

  当用C++编译程序编译时,标识符__cplusplus就会被定义。

#include <stdio.h>
#include <stdlib.h>
void why_me();
int main()
{
    printf( "The file is %s./n", __FILE__ );
    printf( "The date is %s./n", __DATE__ );
    printf( "The time is %s./n", __TIME__ );
    printf( "This is line %d./n", __LINE__ );
    printf( "This function is %s./n", __func__ );
    why_me();
    return 0;
}

void why_me()
{
    printf( "This function is %s/n", __func__ );
    printf( "The file is %s./n", __FILE__ );
    printf( "This is line %d./n", __LINE__ );
}


时常在cpp的代码之中看到这样的代码:

#ifdef __cplusplus
extern "C" {
#endif

//一段代码

#ifdef __cplusplus
}
#endif
  

    这样的代码到底是什么意思呢?首先,__cplusplus是cpp中的自定义宏,那么定义了这个宏的话表示这是一段cpp的代码,也就是说,上面的代码的含义是:如果这是一段cpp的代码,那么加入extern "C"{和}处理其中的代码。

  要明白为何使用extern "C",还得从cpp中对函数的重载处理开始说起。在c++中,为了支持重载机制,在编译生成的汇编码中,要对函数的名字进行一些处理,加入比如函数的返回类型等等.而在C中,只是简单的函数名字而已,不会加入其他的信息.也就是说:C++和C对产生的函数名字的处理是不一样的. 目的就是主要实现C与C++的相互调用问题。


 
c.h的实现
#ifndef _c_h_
#define _c_h_

#ifdef __cplusplus
extern "C" {
#endif

void C_fun();

#ifdef __cplusplus
}
#endif

#endif
-----------------------------------
c.c的实现
#include "c.h"
void C_fun()
{
}
------------------------------------
在cpp.cpp中调用c.c中的C_test()
cpp.cpp的实现
#include "c.h"
int main()
{
     C_fun()
}
其中__cplusplus是C++编译器的保留宏定义.就是说C++编译器认为这个宏已经定义了.
所以关键是extern "C" {}
extern "C"是告诉C++编译器件括号里的东东是按照C的obj文件格式编译的,要连接的话按照C的命名规则去找.
==========================
那么C中是如何调用C++中的函数cpp_fun()呢?
因为先有C后有C++, 所以只能从C++的代码中考虑了.
加入C++中的函数或变量有可能被C中的文件掉用,则应该这样写,也是用extern "C"{}
不过是代码中要加,头文件也要加,因为可能是C++中也调用
--------------------------------------
cpp.h的实现
#ifndef _c_h_
#define _c_h_
#ifdef __cplusplus
extern "C" {
#endif
void CPP_fun();
#ifdef __cplusplus
}
#endif
#endif
.-------------------------------------------
Cpp.cpp的实现
extern "C" {    //告诉C+++编译器,扩号里按照C的命名规则编译
void CPP_fun()
{
     .....
}
 
 
总结
C和C++对函数的处理方式是不同的.extern "C"是使C++能够调用C写作的库文件的一个手段,如果要对编译器提示使用C的方式来处理函数的话,那么就要使用extern "C"来说明。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/508734.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

printf输出格式

printf()格式转换的一般形式如下 %(flags)(width)(.prec)type 以中括号括起来的参数为选择性参数&#xff0c;而%与type则是必要的。底下先介绍type的几种形式 整数 %d 整数的参数会被转成一有符号的十进制数字 %u 整数的参数会被转成一无符号的十进制数字 %o 整数的参数会被转…

C函数实现返回多个值的方法

C语言中&#xff0c;一个函数最多只能实现一个返回值。 int func (int b) { int a5; if (a>b) return a; else return b; return 0; } 通过在函数中使用返回语句&#xff0c;返回一个值给函数&#xff0c;同时终止函数的调用&#xff0c;返回主函数。而在实际操…

汇编中的寄存器

ebp和esp是32位的SP&#xff0c;BP esp是堆栈指针 ebp是基址指针 ESP与SP的关系就象AX与AL&#xff0c;AH的关系.32位CPU所含有的寄存器有&#xff1a;4个数据寄存器(EAX、EBX、ECX和EDX)2个变址和指针寄存器(ESI和EDI) 2个指针寄存器(ESP和EBP)6个段寄存器(ES、CS、SS、…

C字节对齐与C++类对象内存布局

一、什么是对齐&#xff0c;以及为什么要对齐&#xff1a; 1. 现代计算机中内存空间都是按照byte划分的&#xff0c;从理论上讲似乎对任何类型的变量的访问可以从任何地址开始&#xff0c;但实际情况是在访问特定变量的时候经常在特定的内存地址访问&#xff0c;这就需要各类型…

word小结

域代码/域结果显示设置 word选项---->>高级------>>显示域代码而非域值将样式传给其它文件使用 首先启动Word打开包含这些样式的一个文件&#xff0c;然后选择“工具”---->“模板和加载项”。在弹出的对话框中单击“管理器”按钮。在弹出的“管理器”对话框中&…

excel中VBa应用总结

单元格操作Range("C4") 1 很直观&#xff0c;不用多解释了吧[C4] 1 跟Range差不多&#xff0c;但更简洁Cells(4,3) 1 Cells有2个参数Rowindex和ColumnIndex&#xff0c;分别是行号和列号。注意是先行后列Sheets(1).Range("A1").Value 1 使用 Sheets(in…

回调函数的应用

VPP 协议组件提供了许多的函数接口供开发者调用&#xff0c;同时也提供了很多的回调函数接口需要我们去实现&#xff0c;而由协议栈内部来调用。说白了&#xff0c;回调函数就是一个函数指针&#xff0c;协议栈通过一个函数指针&#xff0c;指向我们注册给回调函数接口的函数&a…

VBScript自动打卡

下载插件并注册 将下载后的AutoItX3.dll放到WINDOWS文件夹下&#xff0c;开始--->运行--->regsvr32 AutoItX3.dll 编辑代码&#xff1a;打卡.vbs Set oAutoIt WScript.CreateObject("AutoItX3.Control")Set WShell CreateObject("wscript.shell"…

C/C++语言函数学习(1):atexit、exit、return

/*stdlib.h*void exit(int status);*功 能&#xff1a;终止程序*int atexit(void &#xff08;*func)(void));*功 能: 注册终止函数&#xff0c;在main函数结束以后调用*/ //#include <stdio.h> #include <stdlib.h> void exit_fn1(void) {printf("Exit fun…

C/C++语言函数学习(2)qsort

/***函数名称: qsort*函数原型: void qsort(void *base,size_t num,size_t width,int (*fcmp)(const void *,const void *)*函数功能: 使用快速排序法对数组base进行排序*函数返回:*参数说明:*base 待排序数组*num 数组元素个数*width 每个…

C/C++语言函数学习(3)STL中map容器

/******************************************************************map的基本操作函数&#xff1a;C Maps是一种关联式容器&#xff0c;包含“关键字/值”对begin() 返回指向map头部的迭代器clear(&#xff09; 删除所有元素count() 返回指定元素…

C/C++语言函数学习(4)字符串处理函数

#include <string.h>函数名称: strchr函数原型: char* strchr(char* str,char ch);函数功能: 找出str指向的字符串中第一次出现字符ch的位置函数返回: 返回指向该位置的指针,如找不到,则返回空指针参数说明: str-待搜索的字符串&#xff0c;ch-查找的…

C/C++函数学习(6)容器分类

http://net.pku.edu.cn/~yhf/UsingSTL.htm 三十分钟掌握STL STL容器分三大类&#xff1a;顺序容器(sequence container)、关联容器(associative container)和容器适配器(container adapter)。另外我们熟悉的C语言式数组合string&#xff0c;它们也是一种容器&#xff0c;称为…

Python字符串内建函数

方法 描述 string.capitalize() 把字符串的第一个字符大写 string.center(width) 返回一个原字符串居中,并使用空格填充至长度 width 的新字符串 string.count(str, beg0,endlen(string)) 返回 str 在 string 里面出现的次数&#xff0c;如果 beg 或者 end 指…

巧用快捷键轻松设置Excel单元格格式

巧用快捷键轻松设置Excel单元格格式 在应用程序中使用快捷键&#xff0c;可以使我们避免在键盘与鼠标之间来回切换&#xff0c;从而节省大量的时间&#xff0c;显著地提高工作效率。多掌握一些常用的快捷键&#xff0c;可以使您告别菜鸟时代&#xff0c;迅速成长为电脑应用的高…

perror()与strerror()的应用及区别 man手册查询

perror() 和 strerror() 以一种直观的方式打印出错误信息&#xff0c;对于调试程序和编写优秀的程序非常有用。下面是perror() 与 strerror() 的使用范例及区别&#xff1a;perror()原型&#xff1a;#include <stdio.h>void perror(const char *s);其中&#xff0c;perro…

Linux下解压缩包命令

各种压缩文件的解包与打包命令 .tar 解包&#xff1a;tar xvf FileName.tar打包&#xff1a;tar cvf FileName.tar DirName——————————————— .tar .xz 解包&#xff1a;xz -d openvpn-2.3.5.tar.xz --stdout | tar -xv 打包&#xff1a;tar cvf - openvpn-2.3.…

PyQt学习总结

1&#xff09;QDoubleSpinBox() setRange(min,max) 设置范围Min~maxsetSingleStep(step) 设置步长为stepsetValue(value) 设置当前值为valuesetPrefix("$") 设置前缀为$setSuffix("%"&#xff09; 设置后缀为%selectAl…

Qt样例学习1(数字时钟)

/*main.cpp*/ #include <QApplication> #include <QTextCodec> #include "digitalclock.h"int main(int argc, char *argv[]) {QApplication app(argc, argv);//显示本地化&#xff0c;解决中文乱码.QTextCodec::setCodecForTr(QTextCodec::codecForLoca…

linux网络编程--数据结构与函数原型

套接字有三种类型&#xff1a;流式套接字&#xff08;SOCK_STREAM&#xff09;&#xff0c;数据报套接字&#xff08;SOCK_DGRAM&#xff09;及原始套接字。 socket() | bind() | listen() | socket() a…