幻数是什么_为什么我不接受任何幻数

幻数是什么

我想在一个新项目中建立的第一件事就是使用诸如Checkstyle和Findbugs之类的工具,以便整理一些代码准则并避免可以由静态代码分析确定的错误。

迟早使用这些工具时,人们会偶然碰到一种情况,即人们感觉它已经走到了尽头。 一种这样的情况是检查Checkstyle的幻数 。 它将警告除-1、0、1和2以外的数字文字的任何用法,这些数字文字不用于定义常量。

从结果代码可以看出,许多开发人员对此检查存在问题。 我看过这样的代码:

private static final int FOUR = 4;

并且

private static final int FOUR = 5;

和我一直以来的最爱(我没有弥补!):

firstname = rs.getString(1);
lastname = rs.getString(2);
city = rs.getString(2 + 1);
zip = rs.getString(2 + 2);
country = rs.getString(2 + 2 + 1);

但是,在另一种情况下,讨论开始了。 它具有明显的常数,例如100用于将分数转换为百分比值,或1024用于在字节和千字节之间进行转换。 有人认为这些不是幻数(或幻数,但不是那么坏),因为它们的含义很明显并且不会改变。

我不同意,并且会随时投票决定使它们不变。 原因如下:

  1. 含义不明显。 值* 100是什么意思? 分数是否转换为百分比? 长度是否以米为单位换算为厘米? 还是乘以g * g的近似值,而g是地球上的重力加速度呢? 或者,也许我正在将某事乘以一个数组的大小,恰好是100。无法分辨。 一个具有适当名称的简单常量将解决此问题。
  2. 好的,我同意,其中许多常量不会更改。 但是,定义常量(或方法或类)的目的不是(仅)允许以后进行更改,而是使阅读,理解和推理更加容易。 因此,未来价值是否会改变的问题完全无关紧要。
  3. (这是我在大多数讨论中都遗漏的论点)我只是不想考虑它或让其他人考虑它。 我已经看到了数十个(可能是数百个)实例,其中一个适当命名的常量将有助于极大地理解一段代码。 而且我见过的少数情况可能会损害可读性,而没有哪一种情况会严重影响可读性。 因此:只需提取一个常数并使用它即可。

注意:仅仅因为它是一个常量并不意味着它必须是公共的,甚至不是类级别的字段。 如果仅在单个方法中使用它,则局部变量就可以了。

翻译自: https://www.javacodegeeks.com/2014/12/why-i-wont-accept-any-magic-number.html

幻数是什么

ioctl 幻数一般是通过定义 ioctl 命令时使用的,可以在对应的头文件中查看。在 Linux 中,很多驱动程序都会定义自己的 ioctl 命令,这些命令的幻数一般都会在对应的头文件中定义。比如,在 Linux 内核源码的 include/uapi/linux/fs.h 头文件中,可以找到以下定义: ```c #define _IOC_NRBITS 8 #define _IOC_TYPEBITS 8 #define _IOC_SIZEBITS 14 #define _IOC_DIRBITS 2 #define _IOC_NRSHIFT 0 #define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS) #define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS) #define _IOC_DIRSHIFT (_IOC_SIZESHIFT+_IOC_SIZEBITS) #define _IOC_NONE 0U #define _IOC_WRITE 1U #define _IOC_READ 2U #define _IOC(dir,type,nr,size) \ (((dir) << _IOC_DIRSHIFT) | \ ((type) << _IOC_TYPESHIFT) | \ ((nr) << _IOC_NRSHIFT) | \ ((size) << _IOC_SIZESHIFT)) #define _IOC_TYPECHECK(t) (sizeof(t)) ``` 其中,_IOC_TYPEBITS 定义了 ioctl 命令的幻数长度,这里是 8 位,即一个字节。在定义具体的 ioctl 命令时,可以使用 _IO(type, nr)、_IOR(type, nr, size)、_IOW(type, nr, size)、_IOWR(type, nr, size) 等宏来定义,其中的 type 就是 ioctl 命令的幻数。比如,可以在驱动程序的头文件中找到类似以下的定义: ```c #define MYDRV_IOC_MAGIC 'm' #define MYDRV_IOC_GET_VERSION _IOR(MYDRV_IOC_MAGIC, 1, int) #define MYDRV_IOC_SET_PARAM _IOW(MYDRV_IOC_MAGIC, 2, mydrv_param_t) ``` 其中,MYDRV_IOC_MAGIC 定义了驱动程序的幻数为 'm',MYDRV_IOC_GET_VERSION 和 MYDRV_IOC_SET_PARAM 就是具体的 ioctl 命令。在用户空间程序中,可以通过 ioctl 函数调用这些命令,例如: ```c int fd = open("/dev/mydrv", O_RDWR); int version; if (ioctl(fd, MYDRV_IOC_GET_VERSION, &version) < 0) { perror("ioctl MYDRV_IOC_GET_VERSION failed"); return -1; } printf("My driver version: %d\n", version); close(fd); ``` 在这个例子中,MYDRV_IOC_GET_VERSION 就是一个 ioctl 命令,MYDRV_IOC_MAGIC 定义了这个命令的幻数。用户空间程序通过 ioctl 函数调用这个命令,并且将 version 作为参数传递给内核空间的驱动程序。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值