typedef 与 #define的区别

整理于一篇经典blog,经典原文地址http://www.cnblogs.com/csyisong/archive/2009/01/09/1372363.html

案例一:

通常讲,typedef要比#define要好,特别是在有指针的场合。请看例子:

typedef char *pStr1;

#define pStr2 char *;

pStr1 s1, s2;

pStr2 s3, s4;
在上述的变量定义中,s1、s2、s3都被定义为char *,而s4则定义成了char,不是我们所预期的指针变量,根本原因就在于#define只是简单的字符串替换而typedef则是为一个类型起新名字。

案例二:

下面的代码中编译器会报一个错误,你知道是哪个语句错了吗?

typedef char * pStr;

char string[4] = "abc";

const char *p1 = string;

const pStr p2 = string;

p1++;

p2++;

============解释1:

是p2++出错了。这个问题再一次提醒我们:typedef和#define不同,它不是简单的文本替换。上述代码中const pStr p2并不等于const char * p2。const pStr p2和const long x本质上没有区别,都是对变量进行读限制,只不过此处变量p2的数据类型是我们自己定义的而不是系统固有类型而已。因此,const pStr p2的含义是:限定数据类型为char *的变量p2为只读,因此p2++错误。

读不懂上面这段话是么,
其实也可以多读几次嘛。。
const pStr p2和const long x本质上没有区别,都是对变量进行只读限制。x是一个常量。它初始话之后是不可以改变的。
const pStr p2的含义是:限定数据类型为char *的变量p2为只读。
就可以理解为p2是一个常量。p2自身是不可以改变的。但它的类型是pStr是一个char *,说明它指向的数据是char,不是const char。说明p2指向的数据是可改的。。

============解释2:
const char *p1 = string; 你可以这样理解:(const char) *p1 = string, p1是一个指针,指向const char的东西,这个东西就是string(string是一个字符数组的首地址,它的地址声明后肯定是const的,除非该数组销毁),但是p1是一个指针变量,它是可以递增的,即你看到的p1++,它可以完成从数组的来遍历数组的目的。

而const pStr p2 = string;是这样的:由于p2不是指针,const直接修饰到了p2,即现在的p2是常量了,它的类型是pStr(我们自己定义的类型),相当于const int p2, const long p2等等,const都是直接修饰p2的,只不过int,long是系统类型,而pStr是我们定义的类型。为什么会出现这种效果了,就是因为typedef,它把char *定义成一个复合的类型,要从整体上来理解语义,而不是字符替换后来理解语义。

============解释3:
onst char *p1 = string 意思是说一个指向const char类型的指针。。
p1指针是一个变量。他可以指向任意的char对象。就算不是const定义的char也可以,p1可以指向不同的char对象,因为他是一个变量。但他无论是指向const char对象还是char对象。都不能改变其指向对象的值。就是说上例子p1不能对string做修改。只能读取string的值。

typedef char *pStr
const pStr p2 = string 这里是typedef和指针共用时的坑爹指出。
const pStr p2 = string
pStr const p2 = string
char* const p2 = string 上面3个语句是一个意思。
就是说p2是一个指向非const、char类型的对象的const指针。p2初始化之后就不能够指向第二个对象。但p2可以对string的值进行修改。。

看到这里你可能会觉得这不是说p2++正确么~那么请继续看解释~

p2++是错的。。p2本来就是一个指针。。而且是一个const。。就是说是一个常量指针。。你觉得一个const常量初始化之后还可以++吗。。。上面的解释是错的。。不知道是看什么书的。。你可以弄个程序看看。。我贴一下我刚才test的代码。。

#include<stdio.h>

int main(){
typedef char * pStr;
char string[4] = "abc";
const char *p1 = string;
const pStr p2 = string;
p1++;
p2[2] = ‘e‘;
printf(p1);
printf(p2);return 0;
}
p2指针可以对string进行修改。。可以p2不能动。。他是一个const常量!!!!!!!!!!!!!!!

但是p1可以移动。。但是p1却不能修改。。p2可以改。。可是不能移动。。我不懂怎么把指针的++操作说成了对char数组的操作了。。。
下面是代码。。我是用VS2010测试的。。不知道其他的编译器怎么样。。
#include<stdio.h>

int main(){
typedef char * pStr;
char string[4] = "abc";
const char *p1 = string;
const pStr p2 = string;
p1[1] = ‘f‘;
p1++;
p2[2] = ‘e‘;
p2++;
printf(p1);
printf(p2);
return 0;
}
下面是错误:
1>c:\test\typedef.cpp(8): error C3892: “p1”: 不能给常量赋值
1>c:\test\typedef.cpp(11): error C3892: “p2”: 不能给常量赋值

****
按我朋友的理解,const pStr p2 其中,const修辞的是pStr,而pStr类型实际上还是指针,所以这行是定义了一个常指针。可以理解为定义p2是指向char的常指针,常指针的话,p2++当然就不行。
***

============解释:4:
对  案例二  测试:

typedef.c:51:5: 错误: 向只读位置‘*p1’赋值
typedef.c:52:5: 错误: 令只读变量‘p2’自增

我对char * p的理解:两个部分,char为指向的值,p为指针变量,*只是做声明;
当const char * p1时,const修饰的是char,所以p1不能修改指向的值;
当const PStr p2时,const修饰的是p2,所以p2不能对自身做任何修改;

typedef相当于创建了一个新类型,只能做为整体来看。

============解释5:
其实,在这里主要就是对const的作用范围的理解。
typedef char * pStr;
char string1[4] = "abc";
char string2[4] = "def";
const char *p1 = string1;
const pStr p2 = string1;

p1[1] = ‘f‘; // 此句错
p1++; // 此句对
p1 = string2; // 此句对
p1[1] = ‘x‘; // 此句错

p2[1] = ‘f‘; // 此句对
p2++; // 此句错
p2 = string2; // 此句错

在const char *p1中,const的作用力量在p1所指的内容,也就是说,当p1指向string1时,string1的内容相对于p1来说是常量,是固定的,是不能改变的,所以p1[1] = ‘f‘这一句就是错误的,而p1自身的值(即地址值)是可以改变的,所以p1++和p1 = string2都是正确的。

在const pStr p2中,const的作用力量在p2,即p2是个常量,p2的值实际上是个地址,也就是说,p2已经固定了,它的值是不能变的,但它这个地址所指的内容是可以改变的,所以p2[1] = ‘f‘是对的,但p2 = string2是错误的,因为这句是想将另一个地址赋值给p2。

总体来说,一个是将内容固定为常量,一个是将地址固定为常量,也就是指针常量和常量指针的说法,p1是常量指针,p2是指针常量。这也是C中指针的魅力所在。

****插入语:
只看const 先不换typedef const修饰的是*p1 也就是说*p1这个值不能动 即不能赋值 const修饰的是p2,也就是说p2不能动 但*p2可以赋值

error C3892: ‘p2‘ : you cannot assign to a variable that is const
看一下这个vs2008的错误就应该明白了吧,把这个类型当成系统定义的类型我觉得就比较好理解了,好比:
const int a = 5;
a++;
编译错误的道理是一样的。

******
大家共同进步哦~~

经典原文地址http://www.cnblogs.com/csyisong/archive/2009/01/09/1372363.html

时间: 2024-11-05 06:14:24

typedef 与 #define的区别的相关文章

typedef与#define的区别

1.  typedef typedef故名思意就是类型定义的意思,但是它并不是定义一个新的类型而是给已有的类型起一个别名,在这一点上与引用的含义类似,引用是变量或对象的别名,而typedef定义的是类型的别名.typedef的作用主要有两点: 1.1  简化复杂的类型声明 简化复杂的类型声明,或给已有类型起一含义明确的别名:如: typedef bool (*FuncPointer)(int, double); //声明了一个返回 bool 类型并带有两个(int和double)形参的函数的指针

typedef 和define的区别

typedef 和define的区别 总结一下typedef和#define的区别 1.概念 #define 它在编译预处理时进行简单的替换,不作正确性检查.它是预处理指令. typedef 它在自己的作用域内给一个已经存在的类型一个别名.它是在是在编译时处理的. 例子: #define: #define DO double DO val =5;//相当于 double va =5; #define FUN(X) X+5 int va = FUN(3); //相当于 va = 3+5 typed

typedef和#define的区别——————【Badboy】

typedef 和#define 都常用来定义一个标识符及关键字的别名,但他们之间有关键的区别. typedef 是语言编译过程的一部分; #define是宏定义语句,它本身并不在编译过程中进行,而是在这之前的预处理过程就已经完成了. 要理解两者的关键区别,可以这么来考虑 : 把typedef 看成是一种彻底的"封装"类型,相当于产生了一个新的变量类型(这点与struct 类似,待会会与struct 进行类比来增进理解).而#define 仅仅是进行宏文本替换. typedef 和 #

typedef 与define 的区别

typedef和#define的用法与区别 typedef和#define的用法与区别 一.typedef的用法 在C/C++语言中,typedef常用来定义一个标识符及关键字的别名,它是语言编译过程的一部分,但它并不实际分配内存空间,实例像: typedef    int       INT;typedef    int       ARRAY[10];typedef   (int*)   pINT; typedef可以增强程序的可读性,以及标识符的灵活性,但它也有“非直观性”等缺点. 二.#

c语言声明的解读、typedef与define的区别

读声明: 1.最先从左往右找到最左边的标识符. 2.查看标识符右边的下一个符号.若是方括号,则表示到“...的数组”. 3.如果是一个左圆括号.到右括号为止的内容表示“返回...的函数”. 4.再往右找,如果左边的符号是一个左括号, 这个左括号把已处理的部分声明组合在一起,直到遇见对应的右括号,然后从第二步重新开始. 5.如果是*,表示“指向...的指针”: 如果是const,表示“只读”: 如果是volatile,表示“volatile”: 6.剩下的符号可一并阅读. 练习例子:char *

typedef和define的区别

在使用C语言或者C++开发中,我们离不开typedef和define的使用,typedef相当于我们重新定义了一种类型,而define则只是简单的替换,这里我们简单归总一下二者的差别. 首先,我们可以用其他类型说明符对宏类型名进行扩展,但是对typedef的类型名不能扩展,比如 #define  demo   char 我们可以定义unsigned demo c;完全没问题,但是对于typedef char  demo我们却不能定义成unsigned demo c; 其次,在连续几个变量的声明中

typedef 和 define的区别

类型取别名,还可以定义常量.变量.编译开关 都知道两个在某些情况下是相同的 但是define是在预编译时就会处理掉,进行简单的宏替换,不管正不正确都替换掉,末尾没有分号,有分号连分号也一起替换了. 而typedef则是在已经定义的类型中进行别名的定义. typedef有作用域,define只要是在定义之后,均可以使用 typedef不仅可以定义系统自带的类型,还可以定义用户自定义的类型结构,define的用途在于定义类型取别名,还可以定义常量.变量.编译开关 经典问题: const pint p

typedef 与 define 的区别

1.区别 (1)定义.执行时间.作用域 定义.执行时间: #define pchar char * typedef char *pchar;     定义的格式差别,显而易见的,要注意,define 是不能存在分号的(文本替换),而typedef 是存在逗号的(类型的重命名).     同时,define 由预处理器进行处理,只做简单的文本替换的工作,不做任何检查(正确性检查.作用域检查.类型检查) typedef 是给一个已经存在类型的别名,在编译时候处理. 作用域:     define 只

typedef与define的区别与联系

在C或者C++中,可以通过使用typedef和define来声明新的类型来代替已有的类型.例如: typedef int COUNT; #define COUNT int; 两者的作用都是用COUNT来代表int.虽然两者实现的功能相同,但是实际上却又有很大的差别,要不然也不会同时存在了.下面简单谈一下两者的区别,希望在用到时能够正确的进行选择,以便减少不必要的麻烦: typedef 在C或者C++中,typedef常用来定义一个标识符及关键字的别名,它是语言编译过程的一部分,但它并不实际分配内