博客好久没有更新了,主要是因为工作忙,即便不忙也要看看书,工作了才发现好多东西根本就会直接忘记,因为我们工作用不到!比如c++的东西,现在连虚函数表都不快不记得了,惭愧咯!而且我还发现工作了,看书反倒成了一种非常好的休闲了,不过希望我的朋友,同学们都好.
现在就说说typedef和const之间的那么一道陷阱,而且还很深!
现在也是找工作的时间了,弄清楚这个还是很有好处的,或许很多公司就会用这个来欺负"弱小".
记得好像是<c专家编程>里面说提及了这个问题,上面说typedef和const一起使用之后const使用对象会和想象的不一样,具体的不记得了,n久以前看的书了,hoho,不记得了.
现在我就来说说我的理解,之间的代码就不注意命名规范了,还有一些工作的代码肯定也是不能贴了.
先给一个引子,如果我有一个全局变量,是一个二维数组,现在的问题就是,老板不喜欢全局变量,他要弄成一个static变量,需要封装一下,怎么弄,比如这个二维的变量是:
那么我现在就要让这个静态函数能穿越文件,就用一个函数封装起来,然后,返回这个变量的地址,要么就用直接值拷贝的方法,把值按位复制除去都行,如下操作?
明显不行,二者不是一个东西,int**是一个二维指针,而我的苹果myapple却是一个int (*)[8]类型的变量,这个问题我不知道一般的c语言的书籍里面涉及了否,不过如果好多c++的书籍里面还是涉及到了的.
那么现在的问题就很简单了,只要给一个适当的返回类型就ok了.这样?
有点简单,有点粗暴,却不那么有效!
引入typedef,我们可以把一个很复杂的类型用typedef来实现类型的替代,记住是typedef不是define.先定义类型,然后就是作为函数的返回值就ok咯.
那么就肯简单了,如下给出我们一个正确实现:
如此便ok了.
故事到这里就结束了?还没有!
继续看,我上面的type的定义里面加了一个const,下面我定义一个不加const的类型:
这两个类型的差别仅仅是一个const吗?当然不是,hoho,差别在与const是在星星(指针的星号)前后的问题了,type的类型决定了该类型定义的对象不可修改,因为它是在星号前面,或者说它修饰的是对象本身.而type_2呢,在做类型定义myapple_2的时候加上了const,是不是myapple不能改变了?不是,而是,指针不可变!二维的或许有点复杂,我们用一维指针来作为示例:
xp可以说是一个自定义类型,我在定义xp1的时候加上了const修饰,那么从上面的程序来看,1处是没有问题的,在typedef之后,再在变量定义时候加的const实际上是被编译器放在了星号自后了,那么这个const就表示他修饰的是这个指针而不是变量本身,结果2处就错了,因为我视图修改指针xp1.
那我要把const应用与变量而不是指针,就要把const在typedef的时候带上,放星号前面,那么const就修饰的是变量了,如下:
这样的话,2处就会报错,原因上面已经说过了.
回到二维的,也就比较好理解了
const修饰的是后面数组的地址了.自然也就相当于:
如下,同样也可以给出一个例子:
同样:
这个const就是修饰的变量的值了,1处自然也不对了.
最后还有一个问题要说明的是typedef char *xp;得到的xp类型,可以给他赋值变量的地址,或者数组首元素的地址:
上面的程序里面,只要是能表示一维的都可以给myxp赋值,但是类型一定要完全一致.这里容易出两个问题:
1.一维指针但是类型不一致,当然了,c语言给我们提供了强制类型转换;
2.取数组名的地址,再给myxp赋值,这样也是不对的,因为维度不匹配:
1处就明显不对了,但是有人说,数组名和数组名取引用是一个值啊!却是,但是,对于编译器而言,两者是不一样的,a是char*,而&a是char (*)[100]的类型,a+1得到的是a[1]的地址,而&a+1得到的是什么?我想稍微注意点的同志们都知道是下一个100大小的数组的首地址了,也就是a[100]这个本不应该存在的地址了,而且仅仅是值一样,还是一个char (*)[100]的类型.这个就不说远了.有需要的可以再写一篇文章了.
对于typedef一个二维的指针也可以用类型的方法初始化:
这里1和2自然也是不对的,因为他们的维度也不匹配!
就说这么多吧,好累,下班手工回家咯!
希望大家有什么意见,可以提出来,一起学习.
分享到:
相关推荐
收集了函数指针_extern_typedef_const_static的基本用法。 拿出来供大家共享
本篇文章是对C语言基础知识点(extern,static,typedef,const)的用法进行了详细的分析介绍,需要的朋友可以过来参考下
文章简单介绍了#define,const,typedef三者联系与区别
理解复杂的CC++声明 const, typedef , 函数指针
详细讲述了typedef的用法和高级应用 深入浅出 非常容易理解
typedef int * pint ; #define PINT int * 那么: const pint p ;//p不可更改,但p指向的内容可更改 const PINT p ;//p可更改,但是p指向的内容不可更改。 (const pint p === ( const pint )p) (const PINT p ...
介绍#define和typedef的区别于使用
简单介绍了这两者的区别,可以供初学者参考,以便更深入理解
struct typedef struct 区别
对于初学者而言,看别人的源码时对到处充斥的typedef往往不知所错,而参考书又很少,所以在此给出一个源码,供大家参考 ypedef 声明有助于创建平台无关类型,甚至能隐藏复杂和难以理解的语法。不管怎样,使用 ...
typedef与define的用法,说明typedef和define的区别及各自的特殊用法
typedef struct 与 struct 的区别及初始化 typedef struct 与 struct 的区别及初始化 typedef struct 与 struct 的区别及初始化 typedef struct 与 struct 的区别及初始化 typedef struct 与 struct 的区别及初始化
c语言 typedef的用法详解 typedef 声明,简称typedef
lem using const with a typedef. I hoped you could comment on this sit- uation. I am wondering if we are bumping into some unknown (by us) rule of the C language. “We are using the Hitachi C com- ...
Typedef 声明有助于创建平台无关类型,甚至能隐藏复杂和难以理解的语法。不管怎样,使用 typedef 能为代码带来意想不到的好处,通过本文你可以学习用 typedef 避免缺欠,从而使代码更健壮。
#define是预处理指令 typedef是在编译时处理的 typedef与#define的区别
由于对typedef理解不够,因此从网上摘录了一些资料。比较详细和全面
typedef的四个用途和两个陷阱 用途一: 定义一种类型的别名,而不只是简单的宏替换。可以用作同时声明指针型的多个对象。比如: char* pa, pb; // 这多数不符合我们的意图,它只声明了一个指向字符变量的指针........