命名规范:本人目前C/C++/C#混用,也用MATLAB和JAVA,所以要兼顾
C语言由于使用的编辑器可能较弱,所以需要有辅助的前后缀,C#,MATLAB和JAVA可能不用
方法定义:目前很明确,Pascal命名法,首字母大写,不用表明返回值,可能有模块名_前缀
类型定义:
类,一般直接定义,不用typedef
typedef的应用:
{结构体
枚举
联合}
在C/C++中,应用typedef,是历史遗留问题,统一来弄就是了
如果非要自己定义,那也是小范围使用,看自己习惯了
字符串和数组
str或string:strTest,stringTest,超过三个用短的
arr或array:arrTest,arrayTest,超过三个用短的
变量定义
在C/C++中,有类型前缀,在C#,MATLAB和JAVA中不用
规则12、所有宏定义、枚举常数、只读变量 全用大写字母命名,用下划线分割单词。
在真正项目的实施过程中,需要经常的定义自己的变量类型,特别是使用C语言的项目,那么typedef到底该在什么情况下使用呢?在前面的typedef和#define的区别中介绍了两者的使用差别。本文介绍使用typedef的使用方法和typedef使用时就注意的问题。
定义类型别名
定义一种类型的别名,而不只是简单的宏替换。可以用作同时声明指针型的多个对象。比如:
001
|
char
* pa, pb;
// 这多数不符合我们的意图,它只声明了一个指向字符变量的指针, 和一个字符变量http://furzoom.com/
|
这多数不符合我们的意图,它只声明了一个指向字符变量的指针, 和一个字符变量。
可以使用如下方式:
001
002
|
typedef
char
*
PCHAR
;
// 一般用大写
PCHAR
pa, pb;
// 可行,同时声明了两个指向字符变量的指针
|
虽然:
001
|
char
*pa, *pb;
|
也可行,但相对来说没有用typedef的形式直观,尤其在需要大量指针的地方,typedef的方式更省事。
结合struct使用
用在旧的C代码中(C89),帮助struct。以前的代码中,声明struct新对象时,必须要带上struct,即形式为:
001
|
struct
结构名 对象名
|
如:
001
002
003
004
005
006
|
struct
tagPOINT1
{
int
x;
int
y;
};
struct
tagPOINT1 p1;
|
而在C++中,则可以直接写:
001
|
结构名 对象名
|
即:
001
|
tagPOINT1 p1;
|
使用下面的方式更加安全:
001
002
003
004
005
006
007
|
typedef
struct
tagPOINT
{
int
x;
int
y;
}POINT;
POINT p1;
// 这样就比原来的方式少写了一个struct,比较省事,尤其在大量使用的时候
|
或许,在C++中,typedef的这种用途二不是很大,但是理解了它,对掌握以前的旧代码还是有帮助的,毕竟我们在项目中有可能会遇到较早些年代遗留下来的代码。
定义统一的类型
由于C语言的不同的平台上使用时数据类型会有不同,例如int可能是16位的,也可能是32位的。
用typedef来定义与平台无关的类型。比如定义一个叫 REAL 的浮点类型,在目标平台一上,让它表示最高精度的类型为:
001
|
typedef
long
double
REAL;
|
在不支持 long double 的平台二上,改为:
001
|
typedef
double
REAL;
|
在连 double 都不支持的平台三上,改为:
001
|
typedef
float
REAL;
|
也就是说,当跨平台时,只要改下 typedef 本身就行,不用对其他源码做任何修改。
标准库就广泛使用了这个技巧,比如size_t。
另外,因为typedef是定义了一种类型的新别名,不是简单的字符串替换,所以它比宏来得稳健(虽然用宏有时也可以完成以上的用途)。
复杂类型简单化
为复杂的声明定义一个新的简单的别名。方法是:在原来的声明里逐步用别名替换一部分复杂声明,如此循环,把带变量名的部分留到最后替换,得到的就是原声明的最简化版。例如:
1. 原声明:
001
|
int
*(*a[5])(
int
,
char
*);
|
变量名为a,直接用一个新别名pFun替换a就可以了:
001
|
typedef
int
*(*pFun)(
int
,
char
*);
|
原声明的最简化版:
001
|
pFun a[5];
|
2. 原声明:
001
|
void
(*b[10]) (
void
(*)());
|
变量名为b,先替换右边部分括号里的,pFunParam为别名一:
001
|
typedef
void
(*pFunParam)();
|
再替换左边的变量b,pFunx为别名二:
001
|
typedef
void
(*pFunx)(pFunParam);
|
原声明的最简化版:
001
|
pFunx b[10];
|
3. 原声明:
001
|
doube(*)() (*e)[9];
|
变量名为e,先替换左边部分,pFuny为别名一:
001
|
typedef
double
(*pFuny)();
|
再替换右边的变量e,pFunParamy为别名二
001
|
typedef
pFuny (*pFunParamy)[9];
|
原声明的最简化版:
001
|
pFunParamy e;
|
typedef必须注意的问题
1.typedef是定义了一种类型的新别名,不同于宏,它不是简单的字符串替换。比如:
先定义:
001
|
typedef
char
*
PSTR
;
|
然后:
001
|
int
myFurzoom(
const
PSTR
,
const
PSTR
);
|
const PSTR实际上相当于const char*吗?不是的,它实际上相当于char* const。原因在于const给予了整个指针本身以常量性,也就是形成了常量指针char* const。简单来说,记住当const和typedef一起出现时,typedef不会是简单的字符串替换就行。
2.typedef在语法上是一个存储类的关键字(如auto、extern、mutable、static、register等一样),虽然它并不真正影响对象的存储特性,如:
001
|
typedef
static
int
INTF;
//不可行
|
编译将失败,会提示“指定了一个以上的存储类”。