C/C++中的typedef和#define详解

C/C++中的typedef和#define

前言:

  在C/C++中,我们平时写程序可能经常会用到typedef关键字和#define宏定义命令,在某些情况下使用它们会达到相同的效果,但是它们是有实质性的区别,一个是C/C++的关键字,一个是C/C++的宏定义命令,typedef用来为一个已有的数据类型起一个别名,而#define是用来定义一个宏定义常量。下面谈谈两者在实际使用中应当注意的地方。

1.typedef关键字

typedef是用来声明类型别名的,在实际编写代码过程使用typedef往往是为了增加代码的可读性。它可以为一串很长的类型名起一个别名,那么使用这个别名可以达到与原类型名相同的效果。

如:

typedef int INT;
typedef char CHAR;

就为int和char分别起了一个别名,那么在程序中使用INT a;和int a;达到的效果是等同的。在使用typedef时应注意一下几点:

1)typedef是为一个数据类型起一个新的别名,如typedef int INT;那么要告诉我的是INT表示整型,typedef int* INTPTR;则告诉我们INTPTR是一个指向整型变量的指针类型,这点与#define是决然不同的,#define只是作简单的字符串替换,不表达任何含义。如:

#define INTPTR1 int*
typedef int* INTPTR2;

INTPTR1 p1,p2;
INTPTR2 p3,p4;

INTPTR1 p1,p2;和INTPTR2 p3,p4;这两句的效果决然不同。INTPTR1 p1,p2;进行字符串替换后变成int* p1,p2;要表达的意义是声明一个指针变量p1和一个整型变量p2;而INTPTR2 p3,p4;由于INTPTR2是具有含义的,告诉我们是一个指向整型数据的指针,那么p3和p4都为指针变量,这句相当于int* p1,*p2;从这里可以看出,进行宏替换是不含任何意义的替换,仅仅为字符串替换;而用typedef为一种数据类型起的别名是带有一定含义的。

再看下面这个例子:

#define INTPTR1 int*
typedef int* INTPTR2;

int a=1;
int b=2;
int c=3;
const INTPTR1 p1=&a;
const INTPTR2 P2=&b;
INTPTR2 const p3=&c;

上述代码中,const INTPTR1 p1表示p1是一个常量指针,即不可以通过p1去修改p1指向的内容,但是p1可以指向其他内容;而对于const INTPTR2 p2,由于INTPTR2表示是一个指针类型,因此用const去限定,表示封锁了这个指针类型,因此p2是一个指针常量,不可使p2再指向其他的内容,但可以通过p2修改其当前指向的内容,INTPTR2 const p3同样声明的是一个指针常量。

2)对于宏定义:

#define INT int
unsigned INT a;

这种用法是可行的;

typedef int INT;
unsigned INT a;

是绝对错误的用法。

2.#define宏定义

#define是一个宏定义命令,用来定义一个常量(包括无参常量和有参常量),它本身并不在编译过程中执行,而是在预处理阶段就已经完成了,因此不作任何正确性检查,只进行不关含义的字符串替换。在使用宏定义时,如果稍不注意就会发生错误,而且这个错误往往是你意想不到的。如:

#define ADD(a,b) a+b

int i=1;
int j=2;
int k=3;
int s=ADD(i,j)*k;

程序可能想求算的是(i+j)*k的结果,然而这段程序并没有达到这种效果,由于宏替换只是进行简单的字符串替换,那么ADD(i,j)*k相当于i+j*k,并不是想象中的(i+j)*k。

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

(0)

相关推荐

  • 使用C/C++语言生成一个随机迷宫游戏

    迷宫相信大家都走过,毕竟书本啊啥啥啥的上面都会有迷宫,主要就是考验你的逻辑思维.那么我们学习C/C++也是需要学习到逻辑思维方式的,那今天我就来分享一下,如何用C/C++打造一个简单的随机迷宫游戏.(代码的话我只截取了如何创建迷宫的代码,如果想要全套代码的话可以加群:558502932,群内有很多C/C++学习资料提供学习,大家一起交流进步) 完整版的迷宫游戏效果如下: 代码如下: //创建迷宫 void CreateMaze(int x,int y) { //定义4个方向 int dir[4]

  • 利用C/C++二进制读写png文件的方法示例

    前言 二进制文件不是以ASCII代码存放数据的,它将内存中数据存储形式不加转换地传送到磁盘文件,因此它又称为内存数据的映像文件.因为文件中的信息不是字符数据,而是字节中的二进制形式的信息,因此它又称为字节文件. 对二进制文件的操作也需要先打开文件,用完后要关闭文件.在打开时要用ios::binary指定为以二进制形式传送和存储.二进制文件除了可以作为输入文件或输出文件外,还可以是既能输入又能输出的文件.这是和ASCII文件不同的地方. 需求 最近为了弄OpenGl的纹理代码,发现书上没有图片像素

  • 总结C/C++面试中可能会碰到的字符串指针题

    前言 不知道大家有没有这种体会,很多面试题看似简单,却需要深厚的基本功才能给出完美的解答.企业要求面试者写一个最简单的strcpy函数都可看出面试者在技术上究竟达到了怎样的程度,我们能真正写好一个strcpy函数吗?我们都觉得自己能,可是我们写出的strcpy很可能只能拿到10分中的2分.读者可从本文看到 strcpy函数从2分到10分解答的例子,看看自己属于什么样的层次.此外,还有一些面试题考查面试者敏捷的思维能力. 分析这些面试题,本身包含很强的趣味性;而作为一名研发人员,通过对这些面试题的

  • C/C++实现八大排序算法汇总

    概述排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存. 我们这里说说八大排序就是内部排序. 当n较大,则应采用时间复杂度为O(nlog2n)的排序方法:快速排序.堆排序或归并排序. 快速排序:是目前基于比较的内部排序中被认为是最好的方法,当待排序的关键字是随机分布时,快速排序的平均时间最短: 1. 插入排序-直接插入排序(Straight Insertion Sort) 基本思想: 将一个记录插入到已

  • C/C++ ip地址与int类型的转换实例详解

    C/C++ ip地址与int类型的转换实例详解 前言 最近看道一个面试题目,大体意思就是将ip地址,例如"192.168.1.116"转换成int类型,同时还能在转换回去 思路 ip地址转int类型,例如ip为"192.168.1.116",相当于"."将ip地址分为了4部分,各部分对应的权值为256^3, 256^2, 256, 1,相成即可 int类型转ip地址,思路类似,除以权值即可,但是有部分字符串的操作 实现代码 #include &l

  • C/C++静态类和this指针详解及实例代码

     C/C++静态类和this指针详解 1.静态类 C++的静态成员不仅可以通过对象来访问,还可以直接通过类名来访问. class CBook{ public: static double price;//需要通过类外来进行初始化 } int main(void){ CBook book; book.price;//通过对象来访问 CBook::price//通过类名来访问 return 0; } 静态成员变量 对应静态成员有以下几点需要注意: (1)静态数据成员可以是当前类的类型,而其他数据成员

  • C/C++ 中sizeof('a')对比详细介绍

    C/C++ 中sizeof('a')的值对比详细介绍 C语言: char a = 'a'; sizeof(char) = 1 sizeof(a) = 1 sizeof('a') = 4 C++语言: char a = 'a'; sizeof(char) = 1 sizeof(a) = 1 sizeof('a') = 1 字符型变量是1字节这个没错,奇怪就奇怪在C语言认为'a'是4字节,而C++语言认为'a'是1字节. 原因如下: C99标准的规定,'a'叫做整型字符常量(integer char

  • C/C++ 公有继承、保护继承和私有继承的对比详解

    C/C++ 公有继承.保护继承和私有继承的区别 在c++的继承控制中,有三种不同的控制权限,分别是public.protected和private.定义派生类时,若不显示加上这三个关键字,就会使用默认的方式,用struct定义的类是默认public继承,class定义的类是默认private继承.这和Java有很大的不同,Java默认使用public继承,而且只有公有继承. 1.使用public继承时,派生类内部可以访问基类中public和protected成员,但是类外只能通过派生类的对象访问

  • C/C++中提高查找速度的小技巧

    前言 当看到题目是在一个数组中查找某一个元素,或是在一个字符串中查找某个字符,我们一般都会写出如下代码.但这样的代码虽然简洁明了,但在数组元素很多的情况下,并不是一个很好的解决方案,今天我就来分享一个提高查找速度的小技巧. //在一个int数组中查找某个元素 int find(int A[],int n,int element) { for( int i = 0; i < n; i++ ) { if( A[i] == element ) return i; } return -1; } //在一

  • C/C++函数参数传递机制详解及实例

    C/C++函数参数传递机制详解及实例 概要: C/C++的基本参数传递机制有两种:值传递和引用传递,我们分别来看一下这两种的区别. (1)值传递过程中,需在堆栈中开辟内存空间以存放由主调函数放进来的实参的值,从而成为了实参的一个副本.值传递的特点是被调函数对形参的任何操作都是作为局部变量进行,不会影响主调函数的实参变量的值. (2)引用传递过程中,被调函数的形参虽然也作为局部变量在堆栈中开辟了内存空间,但是这时存放的是由主调函数放进来的实参变量的地址.被调函数对形参的任何操作都被处理成间接寻址,

随机推荐