zoukankan      html  css  js  c++  java
  • typedef 与 #define的区别

    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: est ypedef.cpp(8): error C3892: “p1”: 不能给常量赋值
    1>c: est ypedef.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

  • 相关阅读:
    软件工程基础之二——阅读《软件工程基础》的问题
    软件工程基础之一——个人介绍与计划
    个人介绍
    sudoku
    GitHub地址
    疑问②
    概览提问①
    jsp内置对象
    tomcat的环境变量配置
    构造方法的重载代码
  • 原文地址:https://www.cnblogs.com/hhddcpp/p/4313944.html
Copyright © 2011-2022 走看看