一.typedef主要功能是定义一个已存在类型的别名,但是和宏并存

宏与typedef区别

1.宏定义只是简单的字符串替换

2.typedef定义的类型是类型的别名,typedef后面是一个整体声明,是不能分割的一个整体,具有一定的封装性,不是简单的字符串替换

看下面的例子:

#define PSTR_MACRO char*

typedef char* PSTR

int main()

{

  PSTR piVar1,piVar2;

  PSTR_MACRO piVar3,piVar4;

  int iVar = 100;

  piVar1 = &iVar;

  piVar2 = &iVar;

  piVar3 = &iVar;

  piVar4 = &iVar;

  printf("piVar1 = %0X\r\n",piVar1);

  printf("piVar2 = %0X\r\n",piVar2);

  printf("piVar3 = %0X\r\n",piVar3);

  printf("piVar4 = %0X\r\n",piVar4);

}

输出piVar1 = 19FC78

piVar2 = 19FC78

piVar3 = 19FC78

piVar4 =78

typedef主要为复杂的声明定义简单的别名,它本身是一种存储类的关键字,与auto,extern,mutable,static,register等关键字不能出现在同一个表达式中,如typedef static int nValue

typedef的其它用途

1.用在旧的C代码中,声明struct新对象时,必须带上struct,即形式为struct结构体对象名,例如

struct tagPOINT    为了实现在结构体使用过程中少写声明头部分的struct,可采用      typedef struct tagPOINT

{                                             {

  int x;                                           int x;

  int y;                                           int y;

};                                             }POINT;

struct tagPOINT pl;                                    POINT pl;

在C++中,typedef的这种用途不是很大,但理解了它,对掌握以前的旧代码还是有帮助的

2.另外一个用途就是定义与机器无关的类型,保障代码具有较好的跨平台特性。例如,可定义一个名为REAL_NUM的浮点类型,在目标机器上它可以获得最高的精度

typedef long double REAL_NUM

在不支持long double的机器上,通过typedef可采用如下定义

typedef double REAL_NUM

对于连double都不支持的机器上,通过typdedef可采用如下定义

typedef float REAL_NUM;

采用typedef实现数据类型的定义,只需对typedef本身进行修改,不用对源代码做任何修改,便可以在每一种平台上编译这个使用REAL_NUM类型的应用程序

3.为复杂的声明定义一个简单的名称,简化代码。这一功能可增强代码的可读性和标识符的灵活性

例如

int*(*paFunc[6])(char* pszInput)    简化后为typedef int* (*pFunc)(char* pszInput)    pFunc paFunc[6]

typedef BOOL *CallBackFunc(const char* pszData,const int nDatalength);    CallBackFunc m_pCallBackFunc;

二.static关键字

static有3种用法:静态局部变量,静态全局变量/函数和静态成员变量/函数

1.静态局部变量

static变量分配在全局静态存储区域,在程序的整个运行期间都不会释放。在初次运行时进行初化工作,且只初始化一次。如果不赋初值,编译器会自动赋值0或空字符

static局部变量具有“记忆性”与生存期的“全局性”

记忆性是指在两次函数调用时,在第二次调用进入时,能保持第一次调用时退出时的值

全局性是指一存周期从程序运行时开始,直到程序退出时结束

2.静态全局变量/函数

静态全局变量/函数的静态指的不是存储方式,而是指函数(变量)的作用域为本文件,不能被其他文件所访问

对于全局变量无论是否被static修饰限制,它的存储区域都是静态存储区,生存期都是全局的。

使用静态函数的好处是:不同的程序员编写不同的函数时,不用担心自己定义的函数,是否会与其他文件中的函数同名,因为你编写的函数只是在你的模块或文件中可见

static void FuncA()

3.静态成员变量/函数

(1)静态成员变量:在类内数据成员的声明前加上关键字static,该数据成员就是类的静态数据成员了

class CSaving

{

  private:

    static double m_dInterstRate;

};

double CSaving::m_dInterstRate = 0.05;

static成员变量的特点:

1.静态数据成员和普通数据成员一样遵从public,private,protected访问规则

2.静态数据成员的初始化的格式为:<数据类型><类名>::<静态数据成员名>=<值>

3.修改一个对象中的静态变量,另外一个对象的静态变量也会被修改,所以无论这个类的对象被定义了多少个,静态数据成员在程序中只有一份拷贝,由该类型的所有对象共享访问,即静态成员变量属于类所有,不属于类的实例所有。也就是说即使一个类没有定义任何实例,类中的静态成员也是存在的,也可以正常使用它

静态数据成员存储在全局数据区,静态数据成员定义时要分配空间,所以不能在类声明中定义。另外,类的静态数据成员不占用类的存储大小

与全局变量相比,静态数据成员没有进入程序的全局名字空间,因此不会存在与程序中其他全局名字冲突的可能性。另外,将静态变量声明为private成员可以实现数据信息的隐藏,而全局变量则无法实现

(2)静态成员函数

静态成员函数和静态成员变量一样,它为类的服务而不是为类的具体对象服务。这里需要说明的是:一般普通成员函数都隐含一个this指针(this指针指向类的对象本身),而静态成员函数不存在this指针,因为静态成员函数不属于任何对象,它属于类。因此,静态成员函数无法访问类对象的非静态成员(包含非静态数据成员和非静态成员函数),它只能调用静态成员函数。

因为静态成员函数也属于类的成员函数,所以可以采用访问操作符"."和"->"进行静态成员函数的调用。同样,由于静态成员函数属于类,也可采用下述格式进行静态成员函数的调用

<类名>::<静态成员函数名>(<参数表>)

特点:

1.静态成员可以访问静态成员,但绝对不能访问非静态成员。这是因为静态成员在类定义时便产生和分配空间了,而非静态成员只是在类定义时才会产生并分配空间,所以当静态成员操作非静态成员时一般会报出“访问未定义变量”错误

2.静态成员随着程序的开始运行而产生,而后便一直存在不会消失,只有当程序执行完毕退出后才会释放空间并消失,所以静态成员函数不能在任何函数内分配空间和初始化

3.静态成员不能声明为虚函数。这是因为静态成员函数在对象实例未生成前便可以调用。而如果对象实例未产生,虚函数调用使用的虚函数表未生成,导致虚函数调用时不知调用子类的虚函数还是父类的虚函数

4.非静态成员函数可以任意访问静态成员函数,而静态成员函数只能访问静态成员函数

三.const

const可以说是C++中最为神奇的关键字。它的神奇之处在于:可以通过编译器指定语义上的约束,而不需要花费任何的代价。const的用途多样。例如,在类的外部,可以定义全局作用域的常量,也可以通过添加static来定义文件,函数或程序块作用域的常量。对于指针,通过const可以定义指针是const,其所指向的数据是const或两者都是const

char szGreeting[] = "Hello,world";

char* pszGreeting = "szGreeting";        //非const指针,非const数据

const char* pszGreeting = szGreeting;      //非const指针,const数据

char* const pszGreeting = szGreeting;      //const指针,非const数据

const char* const pszGreeting = szGreeting;   //const指针,const数据

规律如下:

如果const在*的左边,说明指针所指向的对象是常值;如果所指向的对象为常值,const在类型的前面和后面都一样。如果const在*的右边,说明指针是恒值。

最复杂的是const同时出现在*的左右两侧,此时说明指针是恒值,指针所指向的对象也是恒值。

1.函数返回值声明为const

让函数返回一个常量值,经常可以在不降低安全性和效率的前提下减少用户出错的概率。请看以下片段

CRational{}                            //有理数类,支持有理数的加减乘除四则运算

CRational operator*(const rational& lhs,const rational& rhs);    //有理数乘法运算

CRational a,b,c;

(a*b)=c;                              //对a*b的结果赋值,不符合逻辑,但可以通过编译

修改如下

CRational{}                            //有理数类,支持有理数的加减乘除四则运算

const CRational operator*(const rational& lhs,const rational& rhs);    //有理数乘法运算

CRational a,b,c;

(a*b)=c;                              //对a*b的结果赋值,编译器报出编译错误

声明operator*操作符重载函数的返回值为const可以避免对两个数的运算结果赋值问题。对程序员来说,对两个数的运算结果赋值是非常没有道理的。

2.const成员函数

函数具有const属性,这是C++所特有的特征。将成员函数声明为const就是指明这个函数可以被const对象调用

const成员函数的优点

const成员函数可使得类的接口更加容易理解

const成员函数可以与const对象协同工作。这是高效编码十分重要的一个方面

如果成员函数之间的区别仅仅为"是否是const的",那么它们可被重载。很多人忽略这点

当且仅当一个成员函数对所有的数据成员都不做出改动时,才需要将此函数声明为const。也就是说如果一个成员函数声明const的条件是:成员函数不对对象内部做任何修改。它使得错误检查变得更轻松。

3.尽量用const常量替换#define常量定义

在C语言中定义一个int型常量,必须这样定义

#define MAX_LENGTH 100

而C++大可不必,因为这种实现存在很多陷阱。如#define只进行字符替换,没有类型安全检查,并且在字符替换时可能会产生意想不到的错误

通过const实现常量定义。const int MAX_LENGTH = 100

从汇编的角度来看const定义常量,只是给出了对应的内存地址,而不是像#define一样给出的是立即数。const定义的常量在程序运行过程中只有一份拷贝,而#define定义的常量在内存中有若干个拷贝,所以使用const常量可以节省内存。所以尽量用const常量替换#define常量定义

转载于:https://www.cnblogs.com/fenghuan/p/4851660.html

typedef,static,const用法相关推荐

  1. C语言高频率--typedef和const用法详解

    一.typedef用法详解 C语言允许为一个数据类型起一个新的别名,就像给人起"绰号"一样. 起别名的目的不是为了提高程序运行效率,而是为了编码方便.例如有一个结构体的名字是 st ...

  2. #define、typedef与const

    #define.typedef与const #define(宏定义)只是简单的字符串代换(原地扩展),它本身并不在编译过程中进行,而是在这之前(预处理过程)就已经完成了. typedef是为了增加可读 ...

  3. 【C++】C/C++ 中 static 的用法全局变量与局部变量

    C/C++ 中 static 的用法全局变量与局部变量 目录 1. 什么是static? 1.1 static 的引入 1.2 静态数据的存储 2. 在 C/C++ 中static的作用 2.1 总的 ...

  4. C和C++中static的用法及友元

    C和C++中static的用法 文章目录 C和C++中static的用法 一.**C语言中**: 二.**C++中**: 三.**友元**: 一.C语言中: static 修饰全局变量表示该变量只在本 ...

  5. Typedef的一些用法总结

    1.四个用途 用途一: 定义一种类型的别名,而不只是简单的宏替换.可以用作同时声明指针型的多个对象.比如: char* pa, pb; // 这多数不符合我们的意图,它只声明了一个指向字符变量的指针, ...

  6. 《编码规范和测试方法——C/C++版》作业 ·002——函数返回地址、static关键词用法整理

    文章目录 一.函数返回地址的情形 1.函数返回值为指针 二.static关键字用法整理 1.static全局变量 2.static局部变量 3.static函数 4.类的static成员数据 5.类的 ...

  7. C语言返回值是const类型,C++中const用法总结

    1.1.1. 定义普通常量 使用#define来定义常量也是常用方法,但const也可以用来定义常量,在[Effective C++]中建议使用const代替#define来定义常量,因为const定 ...

  8. C++中的const用法

    本文参考<C++编程思想>第八章内容,看过这本书的,请无视以下内容. 在C++中,const一共有四个作用,分别用于值替代.指针.函数参数和返回以及类. 一 值替代 1.const最初的动 ...

  9. 【C++】const 用法总结(非常实用)

    关键字 const 的用法在面试中出现的频率相当之高,但由于 const 用法非常多,时常遗忘,下面对 const 用法进行总结,算是做个笔记吧,方便日后学习!!! 1.const 用于定义常量 co ...

最新文章

  1. reactjs redux集中式状态管理最简入门案例
  2. 怎么使用缓存、缓存穿透、热点数据处理、缓存雪崩解决方案 - 公开课笔记
  3. 【php7扩展开发六】zval的操作
  4. 叛乱2正版怎么创服务器,Insurgency Linux Server 叛乱2创建服务器教程(转steam指南)
  5. FLY主题1.4版本免费完全开源【EMLOG】
  6. 【英语学习】【English L06】U08 News L6 News like to read
  7. WinForm 的定时器使用
  8. Ubuntu使用记录:安装deb软件方法以及apt、apt-get和dpkg的区别
  9. java多线程-创建线程
  10. 【Morgan Stanley IKM在线测试】C++
  11. Vue JSON校验格式化编辑框 -- jsoneditor
  12. ERP进销存系统开发源码交付
  13. mysql数据库日志操作
  14. 【编程语言】品诺试题
  15. Echarts之饼图
  16. ERA5-Land 逐小时数据_累积值(如辐射数据)处理的注意事项
  17. Nginx代理https强制http跳转https
  18. 计算机操作系统习题答案
  19. 查看BMP格式图片的十六进制代码
  20. FFT快速傅里叶变换详解

热门文章

  1. cannot create file怎么解决_内核问题解决方法记录
  2. git pull 报错:git - error: RPC failed; curl 18 transfer closed with outstanding read data remaining 解决
  3. 凭借这份Java面试题集,分布式宝典:限流+缓存+通讯
  4. 【深度学习】高效读取数据的方法(TFRecord)
  5. 【深度学习】医学图像处理之视杯视盘分割调研分析
  6. 【PAT (Advanced Level) Practice】1086 Tree Traversals Again (25 分)
  7. Python内置模块bisect(二分查找实现和快速插入有序序列)
  8. java封装,继承和多态
  9. ajax核心代码提交,ajax表单在Asp.net核心提交后的RedirectToAction
  10. 怎样利用超图客户端打点_渗透测试——XSS利用工具BeEF攻击演示