tag 标签: typedef

相关博文
  • 热度 3
    2023-8-10 12:42
    1523 次阅读|
    0 个评论
    为什么 Linux 内核中不经常使用 typedef? 为什么 Linux 内核中不经常使用 typedef 我们在进行Linux驱动开发过程中,有没有出现过这样的报错? WARNING: do notaddnewtypedefs 不允许使用typedef! 虽然只是一个警告,但是如果你想往开源仓库提交代码,这就是一个必优化项。 那么,为什么Linux内核不建议使用typedef呢? 1、Linus Torvalds 的态度 On Mon, 10 Jun 2002, Linus Torvalds wrote: --snip/snip But in the end, maintainership matters. I personally don't want the typedef culture to get the upper hand, but I don't mind a few of them, and people who maintain their own code usually get the last word. to sum it up: using the "struct mystruct" is recommended , but not a must. Torvalds 本人不太想看到typedef文化占上风,但是维护自己代码的人通常有最后的发言权。 Torvalds 还是比较推荐使用struct mystruct的结构 不易理解 :使用typedef类型,不容易去理解变量的实际类型是什么样子的 不好维护 :由于Linux内核架构的庞大,不同架构之间定义的typedef类型可能并不具有通用性。 Torvalds 原文详见:https://lkml.indiana.edu/hypermail/linux/kernel/0206.1/0402.html 2、内核编码规范 从内核编码规范的角度,来看typedef 内核编码规范给出了typedef使用的一些场合: 完全不透明的对象:隐藏内部对象 明确的整数类型:抽象有助于避免混淆是int型还是long型,如u8/u16/u32 在某些特殊情况下,与标准C99类型相同的新类型。 可在用户空间中使用的类型 内核编码规范详见:https://www.kernel.org/doc/html/v4.10/process/coding-style.html 3、个人看法 个人感觉,从大型项目的开发维护上来说,typedef不建议使用,避免造成类型泛滥,也更加不容易理解。 对于个人开发的小项目,typedef可以完全看自己心情,毕竟typedef褒贬不一。 下面分享一些社区讨论帖子: 为什么我们要在C语言中频繁使用typedef:https://stackoverflow.com/questions/252780/why-should-we-typedef-a-struct-so-often-in-c 为什么Linux编码锋哥不建议使用typedef:https://www.reddit.com/r/C_Programming/comments/dan8vr/why_does_the_linux_kernel_coding_style_guide/?rdt=36702 ▐ 我的圈子: 高级工程师聚集地
  • 热度 17
    2012-9-26 16:55
    1538 次阅读|
    0 个评论
     不管实在C还是C++代码中,typedef这个词都不少见,当然出现频率较高的还是在C代码中。typedef与#define有些相似,但更多的是不同,特别是在一些复杂的用法上,就完全不同了,看了网上一些C/C++的学习者的博客,其中有一篇关于typedef的总结还是很不错,由于总结的很好,我就不加修改的引用过来了,以下是引用的内容( 红色部分是我自己写的内容 )。 用途一: 定义一种类型的别名,而不只是简单的宏替换。可以用作同时声明指针型的多个对象。比如: char* pa, pb; // 这多数不符合我们的意图,它只声明了一个指向字符变量的指针, // 和一个字符变量; 以下则可行: typedef char* PCHAR; PCHAR pa, pb;   这种用法很有用,特别是char* pa, pb的定义,初学者往往认为是定义了两个字符型指针,其实不是,而用typedef char* PCHAR就不会出现这样的问题,减少了错误的发生。 用途二: 用在旧的C代码中,帮助struct。以前的代码中,声明struct新对象时,必须要带上 struct,即形式为: struct 结构名对象名,如: struct tagPOINT1  {     int x;     int y; }; struct tagPOINT1 p1; 而在C++中,则可以直接写:结构名对象名,即:tagPOINT1 p1; typedef struct tagPOINT {     int x;     int y; }POINT; POINT p1; // 这样就比原来的方式少写了一个struct,比较省事,尤其在大量使用的时 候,或许,在C++中,typedef的这种用途二不是很大,但是理解了它,对掌握以前的旧代 码还是有帮助的,毕竟我们在项目中有可能会遇到较早些年代遗留下来的代码。 用途三: 用typedef来定义与平台无关的类型。 比如定义一个叫 REAL 的浮点类型,在目标平台一上,让它表示最高精度的类型为: typedef long double REAL; 在不支持 long double 的平台二上,改为: typedef double REAL; 在连 double 都不支持的平台三上,改为: typedef float REAL; 也就是说,当跨平台时,只要改下 typedef 本身就行,不用对其他源码做任何修改。 标准库就广泛使用了这个技巧,比如size_t。另外,因为typedef是定义了一种类型的新别名,不是简单的字符串替换,所以它比宏来得稳健。       这个优点在我们写代码的过程中可以减少不少代码量哦! 用途四: 为复杂的声明定义一个新的简单的别名。方法是:在原来的声明里逐步用别名替换一部 分复杂声明,如此循环,把带变量名的部分留到最后替换,得到的就是原声明的最简化 版。举例:   原声明:void (*b ) (void (*)()); 变量名为b,先替换右边部分括号里的,pFunParam为别名一: typedef void (*pFunParam)(); 再替换左边的变量b,pFunx为别名二: typedef void (*pFunx)(pFunParam); 原声明的最简化版: pFunx b ;   原声明:doube(*)() (*e) ; 变量名为e,先替换左边部分,pFuny为别名一: typedef double(*pFuny)(); 再替换右边的变量e,pFunParamy为别名二 typedef pFuny (*pFunParamy) ; 原声明的最简化版: pFunParamy e; 理解复杂声明可用的“右左法则”:从变量名看起,先往右,再往左,碰到一个圆括号 就调转阅读的方向;括号内分析完就跳出括号,还是按先右后左的顺序,如此循环,直 到整个声明分析完。举例: int (*func)(int *p); 首先找到变量名func,外面有一对圆括号,而且左边是一个*号,这说明func是一个指针 ;然后跳出这个圆括号,先看右边,又遇到圆括号,这说明(*func)是一个函数,所以 func是一个指向这类函数的指针,即函数指针,这类函数具有int*类型的形参,返回值 类型是int。 int (*func )(int *); func右边是一个 的,原因是 结合)。跳出这个括号,看右边,又遇到圆括号,说明func数 组的元素是函数类型的指针,它指向的函数具有int*类型的形参,返回值类型为int。 这种用法是比较复杂的,出现的频率也不少,往往在看到这样的用法却不能理解,相信以上的解释能有所帮助。 *****以上为参考部分,以下为本人领悟部分***** 使用示例: 1.比较一: #include iostream using namespace std; typedef int (*A) (char, char); int ss(char a, char b) {     cout"功能1"endl;     coutaendl;     coutbendl;     return 0; }   int bb(char a, char b) {     cout"功能2"endl;     coutbendl;     coutaendl;     return 0; } void main() {     A a;     a = ss;     a('a','b');     a = bb;     a('a', 'b'); } 2.比较二: typedef int (A) (char, char); void main() {     A *a;     a = ss;     a('a','b');     a = bb;     a('a','b'); }   两个程序的结果都一样: 功能1 a b 功能2 b a   *****以下是参考部分***** 参考自:http://blog.hc360.com/portal/personShowArticle.do?articleId=57527 typedef 与 #define的区别: 案例一: 通常讲,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 = "abc"; const char *p1 = string; const pStr p2 = string; p1++; p2++;   是p2++出错了。这个问题再一次提醒我们:typedef和#define不同,它不是简单的 文本替换。上述代码中const pStr p2并不等于const char * p2。const pStr p2和 const long x本质上没有区别,都是对变量进行只读限制,只不过此处变量p2的数据类 型是我们自己定义的而不是系统固有类型而已。因此,const pStr p2的含义是:限定数 据类型为char *的变量p2为只读,因此p2++错误。 虽然作者在这里已经解释得很清楚了,可我在这个地方仍然还是糊涂的,真的希望哪位高手能帮忙指点一下,特别是这一句“只不过此处变量p2的数据类型是我们自己定义的而不是系统固有类型而已”,难道自己定义的类型前面用const修饰后,就不能执行更改运算,而系统定义的类型却可以?     最后那个问题: 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 *定义成一个复合的类型,要从整体上来理解语义,而不是字符替换后来理解语义。  
  • 热度 23
    2012-9-10 20:13
    2041 次阅读|
    0 个评论
    typedef char char_t; typedef signed char int8_t; typedef signed short int16_t; typedef signed int int32_t; typedef signed long int64_t; typedef unsigned char uint8_t; typedef unsigned short uint16_t; typedef unsigned int uint32_t; typedef unsigned long uint64_t; typedef float float32_t; typedef double float64_t; typedef long double float128_t;
  • 热度 21
    2012-6-4 11:35
    2126 次阅读|
    0 个评论
    typedef enum { ERROR = 0, SUCCESS = !ERROR } ErrorStatus; 这个代码怎么解释? 这个语句的作用是为数据类型 enum { ERROR = 0, SUCCESS = !ERROR } 定义一个别名ErrorStatus,这样以后定义变量时就写ErrorStatus a;就可以了,而不用写较长的enum{ERROR=0,SUCCESS=!ERROR} a;了.   typedef的用于其实很简单,但是当typedef后面跟个枚举变量这么大一陀代码的时候就不不知怎么理解了。真是不应该。   枚举是一个被命名的整型常数的集合, 枚举在日常生活中很常见。     例如表示星期的SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY,SATURDAY, 就是一个枚举。     枚举的说明与结构和联合相似, 其形式为:     enum 枚举名{     标识符 ,     标识符 ,     ...     标识符 ,     } 枚举变量;     如果枚举没有初始化, 即省掉"=整型常数"时, 则从第一个标识符开始, 顺     次赋给标识符0, 1, 2, ...。但当枚举中的某个成员赋值后, 其后的成员按依次     加1的规则确定其值。     例如下列枚举说明后, x1, x2, x3, x4的值分别为0, 1, 2, 3。     enum string{x1, x2, x3, x4}x;     当定义改变成:     enum string     {     x1,     x2=0,     x3=50,     x4,     }x;     则x1=0, x2=0, x3=50, x4=51     注意:     1. 枚举中每个成员(标识符)结束符是",", 不是";", 最后一个成员可省略     ","。     2. 初始化时可以赋负数, 以后的标识符仍依次加1。     3. 枚举变量只能取枚举说明结构中的某个标识符常量。     例如:     enum string     {     x1=5,     x2,     x3,     x4,     };     enum strig x=x3;     此时, 枚举变量x实际上是7。     enum   关键字在c中用的是比较多的,它常用来定义标记整型常量,你去看许多操作系统的源代码,都有用这个关键字来一次定义许多标记整型常量,其实它相当于定义一个整型常量的表,方便应用时查找。当然他的大部分功能都可以被宏定义代替,不过毕竟enum关键字定义的东东是支持类型检查的,可以用编译器来发现一些错误(enum定义的只能是整型的常量表)  
  • 热度 19
    2011-12-24 23:42
    2338 次阅读|
    2 个评论
    实习,让我懂起一些道理! 学习STM32; 【1】、遇到的第一个问题:No section matches selector - no section to be FIRST/LAST.  原因就是少添加了一个启动文件! http://topic.csdn.net/u/20100822/17/aae54447-84bb-4141-aaad-c0c9de580c6a.html?119612360  http://www.keil.com/forum/15145/ 【2】、结构体定义 typedef struct 用法详解和用法小结 typedef是类型定义的意思。typedef struct 是为了使用这个结构体方便。 具体区别在于: 若struct node {}这样来定义结构体的话。在申请node 的变量时,需要这样写,struct node n; 若用typedef,可以这样写,typedef struct node{}NODE; 。在申请变量时就可以这样写,NODE n; 区别就在于使用时,是否可以省去struct这个关键字。 第三篇:struct和typedef struct 分三块来讲述: 1 首先: 在C中定义一个结构体类型要用typedef: typedef struct Student { int a; }Stu; 于是在声明变量的时候就可:Stu stu1; 如果没有typedef就必须用struct Student stu1;来声明 这里的Stu实际上就是struct Student的别名。 另外这里也可以不写Student(于是也不能struct Student stu1;了) typedef struct { int a; }Stu; 但在c++里很简单,直接 struct Student { int a; }; 于是就定义了结构体类型Student,声明变量时直接Student stu2; =========================================== 2其次: 在c++中如果用typedef的话,又会造成区别: struct Student { int a; }stu1;//stu1是一个变量 typedef struct Student2 { int a; }stu2;//stu2是一个结构体类型 使用时可以直接访问stu1.a 但是stu2则必须先 stu2 s2; 然后 s2.a=10; =========================================== 3 掌握上面两条就可以了,不过最后我们探讨个没多大关系的问题 如果在c程序中我们写: typedef struct { int num; int age; }aaa,bbb,ccc; 这算什么呢? 我个人观察编译器(VC6)的理解,这相当于 typedef struct { int num; int age; }aaa; typedef aaa bbb; typedef aaa ccc; 也就是说aaa,bbb,ccc三者都是结构体类型。声明变量时用任何一个都可以,在c++中也是如此。但是你要注意的是这个在c++中如果写掉了typedef关键字,那么aaa,bbb,ccc将是截然不同的三个对象。 第四篇:C/C++中typedef struct和struct的用法 struct _x1 { ...}x1; 和 typedef struct _x2{ ...} x2; 有什么不同? 其实, 前者是定义了类_x1和_x1的对象实例x1, 后者是定义了类_x2和_x2的类别名x2 , 所以它们在使用过程中是有取别的.请看实例1. 结构也是一种数据类型, 可以使用结构变量, 因此, 象其它 类型的变量一样, 在使用结构变量时要先对其定义。 定义结构变量的一般格式为: struct 结构名 { 类型 变量名; 类型 变量名; ... } 结构变量; 结构名是结构的标识符不是变量名。 另一种常用格式为: typedef struct 结构名 { 类型 变量名; 类型 变量名; ... } 结构别名; 另外注意: 在C中,struct不能包含函数。在C++中,对struct进行了扩展,可以包含函数。 ====================================================================== 实例1: struct.cpp #include iostream using namespace std; typedef struct _point{ int x; int y; }point; //定义类,给类一个别名 struct _hello{ int x,y; } hello; //同时定义类和对象 int main() { point pt1; pt1.x = 2; pt1.y = 5; cout "ptpt1.x=" pt1.x "pt.y=" pt1.y endl; //hello pt2; //pt2.x = 8; //pt2.y =10; //cout"pt2pt2.x=" pt2.x "pt2.y="pt2.y endl; //上面的hello pt2;这一行编译将不能通过. 为什么? //因为hello是被定义了的对象实例了. //正确做法如下: 用hello.x和hello.y hello.x = 8; hello.y = 10; cout "hellohello.x=" hello.x "hello.y=" hello.y endl; return 0; } 第五篇:问答 Q: 用struct和typedef struct 定义一个结构体有什么区别?为什么会有两种方式呢? struct Student { int a; } stu; typedef struct Student2 { int a; }stu2; A: 事实上,这个东西是从C语言中遗留过来的,typedef可以定义新的复合类型或给现有类型起一个别名,在C语言中,如果你使用 struct xxx { }; 的方法,使用时就必须用 struct xxx var 来声明变量,而使用 typedef struct { }的方法 就可以写为 xxx var; 不过在C++中已经没有这回事了,无论你用哪一种写法都可以使用第二种方式声明变量,这个应该算是C语言的糟粕。 用法小结 第一、四个用途 用途一: 定义一种类型的别名,而不只是简单的宏替换。可以用作同时声明指针型的多个对象。比如: char* pa, pb; // 这多数不符合我们的意图,它只声明了一个指向字符变量的指针, // 和一个字符变量; 以下则可行: typedef char* PCHAR; // 一般用大写 PCHAR pa, pb; // 可行,同时声明了两个指向字符变量的指针 虽然: char *pa, *pb; 也可行,但相对来说没有用typedef的形式直观,尤其在需要大量指针的地方,typedef的方式更省事。 用途二: 用在旧的C的代码中(具体多旧没有查),帮助struct。以前的代码中,声明struct新对象时,必须要带上struct,即形式为: struct 结构名 对象名,如: struct tagPOINT1 { int x; int y; }; struct tagPOINT1 p1; 而在C++中,则可以直接写:结构名 对象名,即: tagPOINT1 p1; 估计某人觉得经常多写一个struct太麻烦了,于是就发明了: typedef struct tagPOINT { int x; int y; }POINT; POINT p1; // 这样就比原来的方式少写了一个struct,比较省事,尤其在大量使用的时候 或许,在C++中,typedef的这种用途二不是很大,但是理解了它,对掌握以前的旧代码还是有帮助的,毕竟我们在项目中有可能会遇到较早些年代遗留下来的代码。 http://blog.sina.com.cn/s/blog_4fdabc820100fsxu.html  
相关资源
  • 所需E币: 0
    时间: 2021-4-13 17:28
    大小: 6.67KB
    上传者: LiuSirSZ
    C语言中typedef用法.rar
  • 所需E币: 0
    时间: 2020-12-10 22:31
    大小: 38.5KB
    上传者: LGWU1995
    C语言中typedef用法
  • 所需E币: 4
    时间: 2019-12-24 10:34
    大小: 35KB
    上传者: 238112554_qq
    #define的用法及与typedef的区别#define的用法及与typedef的区别1.简单的define定义#defineMAXTIME1000一个简单的MAXTIME就定义好了,它代表1000,如果在程序里面写if(i编译器在处理这个代码之前会对MAXTIME进行处理替换为1000。这样的定义看起来类似于普通的常量定义CONST,但也有着不同,因为define的定义更像是简单的文本替换,而不是作为一个量来使用,这个问题在下面反映的尤为突出。2.define的“函数定义”define可以像函数那样接受一些参数,如下#definemax(x,y)(x)>(y)?(x):(y);这个定义就将返回两个数中较大的那个,看到了吗?因为这个“函数”没有类型检查,就好像一个函数模板似的,当然,它绝对没有模板那么安全就是了。可以作为一个简单的模板来使用而已。但是这样做的话存在隐患,例子如下:#defineAdd(a,b)a+b;在一般使用的时候是没有问题的,但是如果遇到如:c*Add(a,b)*d的时候就会出现问题,代数式的本意是a+b然后去和c,d相乘,但是因为使用了define(它只是一个简单的替换),所以式子实际上变成了c*a+b*d另外举一个例子:#definepin(int*);pina,b;本意是a和b都是int型指针,但是实际上变成int*a,b;a是int型指针,而b是int型变量。这是应该使用typedef来代替define,这样a和b就都是int型指针了。所以我们在定义的时候,养成一个良好的习惯,建议所有的层次都要加括号。3.宏的单行定义#defineA(x)T_##x#defineB(x)#@x#defineC(x)#x我们假设:……