网页资讯视频图片知道文库贴吧地图采购
进入贴吧全吧搜索

 
 
 
日一二三四五六
       
       
       
       
       
       

签到排名:今日本吧第个签到,

本吧因你更精彩,明天继续来努力!

本吧签到人数:0

一键签到
成为超级会员,使用一键签到
一键签到
本月漏签0次!
0
成为超级会员,赠送8张补签卡
如何使用?
点击日历上漏签日期,即可进行补签。
连续签到:天  累计签到:天
0
超级会员单次开通12个月以上,赠送连续签到卡3张
使用连续签到卡
12月10日漏签0天
c语言吧 关注:801,502贴子:4,372,990
  • 看贴

  • 图片

  • 吧主推荐

  • 视频

  • 游戏

  • 17回复贴,共1页
<<返回c语言吧
>0< 加载中...

[水] typeof的小妙用

  • 只看楼主
  • 收藏

  • 回复
  • XeO2
  • 小吧主
    14
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
这个帖子是受到N3450(https://www.open-std.org/JTC1/SC22/WG14/www/docs/n3450.txt)的启发


  • XeO2
  • 小吧主
    14
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
例行提示:typeof是C23的特性,做题和考试的时候请不要使用。
不过现在考试应该都结束了吧,这里提前给各位拜个早年!
o(≧v≦)o


2025-12-10 13:58:56
广告
不感兴趣
开通SVIP免广告
  • XeO2
  • 小吧主
    14
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
C23增加了关键词typeof和typeof_unqual,这俩和sizeof很像,可以使用“表达式”或“类型名”作为操作数:

typeof(表达式)很好理解,用来获得“表达式”的类型,这正是typeof的初衷,那typeof(类型名)有什么用呢?


  • XeO2
  • 小吧主
    14
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
咋一看这种原地打转的做法好像无甚意义,其实不然。
-
C标准库有个函数叫signal,它肯定不是众多库函数中最复杂的,但是

我相信大多数人第一眼看到它的时候,都会高声惊呼:
“天呐!这是个什么鬼东西?”
-
为了解释这个魔鬼声明到底在说啥,一般会先祭出一个typedef:
typedef void (*sig_func)(int);
然后signal的声明就可以改写成:
sig_func signal(int sig, sig_func func);
看着很唬人,其实就是参数里面有个函数指针,返回类型也是函数指针。
-
N3450要解决的也是同样的问题,只不过现在我们有typeof了,就不需要再写个typedef了:
typeof(void (int)) *signal(int sig, typeof(void (int)) *func);
这样看着也是舒服多了,毕竟typedef再怎么好也要占用一个标识符呢。
-
话说typeof作为一个GNU扩展也存在挺长时间了,不过现在头文件里面好像还没有这种写法。


  • XeO2
  • 小吧主
    14
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
看过上面那个例子,许多灵感就源源不断地出现了。
-
众所周知,指针是许多C语言学习者的一道难关,比如下面这个声明:
int* p1, p2, p3;
这是一种极具误导性的写法,在这个声明中,只有p1是指针,p2和p3都不是。
-
不过没关系,我们可以用typedef:
typedef int *pint;
pint p1, p2, p3;
这样p1, p2, p3就都是指针了。
-
看到这里你肯定已经明白了,我们不是有typeof吗?管上:
typeof(int*) p1, p2, p3;
-
这时候肯定有人就要这样说了:“好极,好极!这种写法是很清楚,可是为什么不用传统写法呢?
int *p1, *p2, *p3;
这样不是更简短吗?”


  • XeO2
  • 小吧主
    14
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
好问题!不过接下来这个想必没有人能够拒绝:
typeof(uint8_t [16][16]) r, g, b, a;
(Java:怎么感觉有人在学我?Σ(っ °Д °;)っ)
-
如果用传统写法,会变成什么样呢:
uint8_t r[16][16], g[16][16], b[16][16], a[16][16];
看着更长不说,一不小心手抖还容易写错。
-
这还只是最简单、最基础的,如果是稍微复杂些的声明,typeof的优势就更明显了。
-
当然了,对于那些非常复杂的声明,typedef的地位还是无可取代的。


  • XeO2
  • 小吧主
    14
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
除了简化声明,typeof还让一部分曾经依赖于实现定义的标准库类型有了标准化的定义方法。
-
size_t是sizeof运算符的结果类型,它的具体定义是随平台变化的,所以你有可能在头文件里面看到:

现在有了typeof,我们就可以按照标准里面的描述

把它定义成这样:
typedef typeof(sizeof(0)) size_t;
-
ptrdiff_t是两个指针相减的结果类型,

现在可以把它定义成这样:
typedef typeof((int*)0-(int*)0) ptrdiff_t;
-
wchar_t是以L为前缀的字符常量的类型,


现在可以把它定义成这样:
typedef typeof(L'0') wchar_t;
-
更不要说C23新加入的nullptr_t,

这是它唯一的标准化定义方式。


  • XeO2
  • 小吧主
    14
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
你可能会问:“这不是循环定义么?”
-
这不重要,反正编译器会帮我们兜底的,苦一苦编译器,骂名……
-
哪有骂名啊?大家都拍手称好。
-
(从实现的角度来说这还真不算循环定义,毕竟用语言本身的特性造标准库,天经地义)


2025-12-10 13:52:56
广告
不感兴趣
开通SVIP免广告
  • XeO2
  • 小吧主
    14
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
typeof还有什么新奇的用法,也欢迎大家各抒己见。
-
EOF


  • GTA小鸡
  • 吧主
    14
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
其实typeof就是C语言的decltype


  • 残-念
  • 异能力者
    6
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
用的最多的时候是在结构体定义的时候,这样之后就不用struct了


  • 香菜味包子
  • 超能力者
    9
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
#define max(a,b) (typeof(a) _a = a, typeof(b) _b = b ; _a > _b ? _a : _b)


登录百度账号

扫二维码下载贴吧客户端

下载贴吧APP
看高清直播、视频!
  • 贴吧页面意见反馈
  • 违规贴吧举报反馈通道
  • 贴吧违规信息处理公示
  • 17回复贴,共1页
<<返回c语言吧
分享到:
©2025 Baidu贴吧协议|隐私政策|吧主制度|意见反馈|网络谣言警示