在extern声明外部结构体变量时,遇到问题如下:
a.c文件
struct STRUCT_PLC_MDL_ProductInfo {
Uint16 ManufacturerID; // 路由模块厂商代码
Uint16 ModelID; // 路由模块芯片代码
union {
Uint8 BS[3];
struct {
Uint8 YY; // 年BCD码
Uint8 MM; // 月BCD码
Uint8 DD; // 日BCD码
} bytes;
} VersionDate; // 路由模块版本日期
Uint16 VersionID; // 路由模块版本号
Uint8 COMType; // 路由模块通信方式
Uint8 CH_NUM; // 路由模块信道个数
Uint8 ProductID[6]; // 路由模块生产编号
Uint8 STR_PMType[10]; // 路由模块类型型号(ASCII码)
Uint8 STR_ProductDate[10]; // 路由模块生产日期(ASCII码)
Uint8 STR_PMCopyRight[32]; // 路由模块版本信息(ASCII码)
Uint8 STR_PMManufacturer [32]; // 路由模块厂商信息(ASCII码)
};
const struct STRUCT_PLC_MDL_ProductInfo PLC_MDL_ProductInfo = {\
0x7068, 0x6463, {0x11, 0x02, 0x03}, 0x0000, 0x02, 0x01, \
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, "PLR-M1.0 ", "2011-02-10", \
"路由模块版本信息", \
"路由模块厂商信息" };
a.h文件
extern const struct STRUCT_PLC_MDL_ProductInfo PLC_MDL_ProductInfo;
b.c文件
#include “a.h”
Uint16 a;
a = PLC_MDL_ProductInfo. ModelID;
编译出错,提示a.h文件中的PLC_MDL_ProductInfo必须是一个结构体或者共用体。
于是就很困惑:按之前的了解,extent声明外部变量不都是这样写的吗,直接声明就行了,在a.h中声明变量PLC_MDL_ProductInfo,然后在b.c中包含头文件a.h,不就可以用变量PLC_MDL_ProductInfo了吗?然而这里确报错了。
最后,经过询问别人,查询资料,知晓大概原因:之前的extern声明变量遇到的都是基本类型的外部变量,然而这里确是声明的外部变量却是构造类型(结构体)类型。问题就出在这里。a.h中虽然声明了结构体变量PLC_MDL_ProductInfo,但是却没有该结构体的定义实体,所以编译器就报错了。
于是改动如下:
a.c文件
#include “a.h”
const struct STRUCT_PLC_MDL_ProductInfo PLC_MDL_ProductInfo = {\
0x7068, 0x6463, {0x11, 0x02, 0x03}, 0x0000, 0x02, 0x01, \
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, "PLR-M1.0 ", "2011-02-10", \
"路由模块版本信息", \
"路由模块厂商信息" };
a.h文件
struct STRUCT_PLC_MDL_ProductInfo {
Uint16 ManufacturerID; // 路由模块厂商代码
Uint16 ModelID; // 路由模块芯片代码
union {
Uint8 BS[3];
struct {
Uint8 YY; // 年BCD码
Uint8 MM; // 月BCD码
Uint8 DD; // 日BCD码
} bytes;
} VersionDate; // 路由模块版本日期
Uint16 VersionID; // 路由模块版本号
Uint8 COMType; // 路由模块通信方式
Uint8 CH_NUM; // 路由模块信道个数
Uint8 ProductID[6]; // 路由模块生产编号
Uint8 STR_PMType[10]; // 路由模块类型型号(ASCII码)
Uint8 STR_ProductDate[10]; // 路由模块生产日期(ASCII码)
Uint8 STR_PMCopyRight[32]; // 路由模块版本信息(ASCII码)
Uint8 STR_PMManufacturer [32]; // 路由模块厂商信息(ASCII码)
};
extern const struct STRUCT_PLC_MDL_ProductInfo PLC_MDL_ProductInfo;
b.c文件
#include “a.h”
Uint16 a;
a = PLC_MDL_ProductInfo. ModelID;
将a.c中结构体struct STRUCT_PLC_MDL_ProductInfo的定义放到a.h中,自然a.c中就要加一句#include “a.h”,否则就没法定义变量PLC_MDL_ProductInfo了。
然后编译,就没有错误了。
但是依然有疑惑,把结构体定义的实体放到a.h中,然后声明外部变量PLC_MDL_ProductInfo,这肯定就没错了。但是,我们知道声明基本类型的外部变量时,如extern int A;可以省略变量类型,直接写为extern A;。于是我就把a.h中的变量声明写成extern PLC_MDL_ProductInfo;,编译就出错了,提示a.h文件中的PLC_MDL_ProductInfo必须是一个结构体或者共用体。看来是不能省略变量类型了。
因此,对于声明外部构造类型(结构体,共用体)变量,要注意两点,这两点也是和声明外部基本类型变量的区别。
一、声明外部构造类型变量时,该文件中必须要有构造类型的定义实体,否则会报错。
二、声明外部构造类型变量时,不能省略变量类型,否则也会报错。(声明外部基本类型变量时,却可以省略变量类型)。