C 语言之 auto / register / static / extern

说明


  • auto
  • register
  • static
  • extern

图示说明


  1. auto 类型

在这里插入图片描述

  1. register 类型

在这里插入图片描述

  1. static 类型

在这里插入图片描述

在这里插入图片描述

  1. extern 类型

在这里插入图片描述

在这里插入图片描述

extern 详解


参考博客:c/c++:extern,extern "C"

参考博客:extern “C”的作用详解

参考博客:C++函数重载以及extern "C"

文章的精华如下:

  1. 情景一
// A.h
char a[2];

// B.h
extern char * a;

错误!!!原因在于,指向类型 T 的指针并不等价于类型 T 的数组

  1. 情景二
// A.h
int i;  // 全局变量

// B.h
int i;  // 全局变量

错误!!!原因在于,在编译阶段,各个文件中定义的全局变量相互是透明的,编译A时觉察不到B中也定义了 i,同样,编译B时觉察不到A中也定义了 i。但是到了链接阶段,要将各个文件的内容“合为一体”,因此,如果某些文件中定义的全局变量名相同的话,在这个时候就会出现重复定义的错误。

正确做法是在 B.h 中的 int i; 前面加上 extern 。extern int i; 仅仅是一个变量的声明,其并不是在定义变量i,并未为 i 分配内存空间。变量 i 在所有模块中作为一种全局变量只能被定义一次,否则会出现连接错误。

  1. 情景三
// A.h
void foo(){}

// B.h
extern void foo(){}

当函数提供方单方面修改函数原型时,如果使用方不知情继续沿用原来的 extern 申明,这样编译时编译器不会报错。但是在运行过程中,因为少了或者多了输入参数,往往会造成系统错误。目前业界针对这种情况的处理没有一个很完美的方案,通常的做法是提供方在自己的xxx_pub.h中提供对外部接口的声明,然后调用包涵该文件的头文件,从而省去 extern 这一步,以避免这种错误。

  1. 情景四
  #ifdef __cplusplus
  #if __cplusplus
		extern "C" {
  #endif
  #endif /* __cplusplus */

  // Todo...

  #ifdef __cplusplus
  #if __cplusplus
      
}
  #endif
  #endif /* __cplusplus */

C++ 在编译的时候为了解决函数的多态问题,会将函数名和参数联合起来生成一个中间的函数名称,而 C 语言则不会,因此会造成链接时找不到对应函数的情况,此时 C 函数就需要用 extern “C” 进行链接指定,这告诉编译器,请保持我的名称,不要给我生成用于链接的中间函数名。

  1. 情景五
// 模块 A 头文件 moduleA.h
#ifndef MODULE_A_H
#define MODULE_A_H

int foo( int x, int y );

#endif

// 在模块 B 中引用该函数:
// 模块 B 实现文件 moduleB.cpp
#include "moduleA.h"
foo(2, 3);

正确,直接包含头文件调用

  1. 情景六
// 模块 A 头文件 moduleA.h
#ifndef MODULE_A_H
#define MODULE_A_H

extern "C" int foo( int x, int y );  // 这里加了 extern "C"

#endif

// 在模块 B 中引用该函数:
// 模块 B 实现文件 moduleB.cpp
#include "moduleA.h"
foo(2, 3);

错误!!!B 模块中将 foo(int, int) 转化为了 foo_int_int() 函数,但是在 A 中没有这样的函数!!!

C++ 调用 C 详解


// C 语言头文件:cExample.h
#ifndef C_EXAMPLE_H
#define C_EXAMPLE_H

  extern int add(int x, int y);

#endif

// C 语言实现文件:cExample.c
#include "cExample.h"

int add( int x, int y ){
      return x + y;
}

// C++ 实现文件,调用 add()方法:cppFile.cpp
extern "C" {
    #include "cExample.h" 
}

int main(int argc, char *argv[]){
    add(2, 3);
    return 0; 
}

C 调用 C++ 详解


// C++ 头文件 cppExample.h
#ifndef CPP_EXAMPLE_H
#define CPP_EXAMPLE_H

  extern "C" int add( int x, int y );
 
#endif
 
//C++ 实现文件 cppExample.cpp
#include "cppExample.h"
 
int add( int x, int y ){
  return x + y;
}
 
// C 实现文件:cFile.c
// 这样会编译出错:#include "cppExample.h" 
 
extern int add( int x, int y );
 
int main( int argc, char* argv[] ){
  add( 2, 3 );
  return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值