是否有printf宽度说明符可以应用于浮点说明符,该说明符会自动将输出格式化为必要的有效位数,以便在重新扫描字符串时,获取原始浮点值?
例如,假设我打印float到2小数位数的精度:
float foobar = 0.9375;
printf("%.2f", foobar); // prints out 0.94
Run Code Online (Sandbox Code Playgroud)
当我扫描输出时0.94,我没有符合标准的保证我将获得原始的0.9375浮点值(在这个例子中,我可能不会).
我想要一种方法告诉printf自动将浮点值打印到必要的有效位数,以确保它可以扫描回传递给的原始值printf.
我可以使用一些宏float.h来导出要传递的最大宽度printf,但是是否已经有一个说明符可以自动打印到必要的有效位数 - 或者至少是最大宽度?
pthread_create看起来像这样的函数头:
int pthread_create(pthread_t * thread,
const pthread_attr_t * attr,
void * (*start_routine)(void *),
void *arg);
Run Code Online (Sandbox Code Playgroud)
我理解这一切除了函数指针start_routine的形式void* (*fpointer) (void*),这意味着它接受一个void指针并返回一个void指针.
它所采用的void指针只是一种将参数传递给start_routine的方法,我得到了那个部分,但是我不明白为什么函数返回一个void指针?什么代码甚至会注意到void指针?
我是一名学习C++的C程序员.在C中,有一个常用的goto习惯用法来处理错误并从函数中干净地退出.我已经读过,在面向对象的程序中,通过try- catchblocks的异常处理是首选,但我在使用C++实现这个范例时遇到了麻烦.
以C中的以下函数为例,它使用了goto错误处理范例:
unsigned foobar(void){
FILE *fp = fopen("blah.txt", "r");
if(!fp){
goto exit_fopen;
}
/* the blackbox function performs various
* operations on, and otherwise modifies,
* the state of external data structures */
if(blackbox()){
goto exit_blackbox;
}
const size_t NUM_DATUM = 42;
unsigned long *data = malloc(NUM_DATUM*sizeof(*data));
if(!data){
goto exit_data;
}
for(size_t i = 0; i < NUM_DATUM; i++){
char buffer[256] = "";
if(!fgets(buffer, sizeof(buffer), fp)){
goto exit_read;
}
data[i] = …Run Code Online (Sandbox Code Playgroud) 我今天看到了这段摘录:
在大多数较旧的微处理器上,按位运算比加法和减法运算稍快,并且通常比乘法和除法运算快得多.在现代体系结构中,情况并非如此:按位运算通常与添加速度相同(尽管仍然比乘法更快).
我很好奇为什么按位操作比旧微处理器上的加/减操作稍快一些.
我能想到的只会导致延迟的是,实现加/减的电路取决于几级逻辑门(并行加法器和诸如此类),而按位运算则具有更简单的电路实现.这是什么原因?
我知道算术和按位运算都在现代处理器的一个时钟内执行,但纯粹谈到电路的传播时间,理论上现在处理器中的延迟仍然存在吗?
最后,我有一个关于按位移位操作执行的概念C问题:
unsigned x = 1;
x <<= 5;
unsigned y = 0;
y += 32;
Run Code Online (Sandbox Code Playgroud)
双方x并y应持有的价值32,但它采取5个独立左移获得x该值(中位运算的变化通过管道实现)?为了澄清,我纯粹是在询问电路行为而不是时钟周期数.
c bit-manipulation cpu-architecture bitwise-operators digital-logic
./configure在Windows中相当于什么?
有时我下载一个C/C++库,当我使用make时,它会显示"use ./configure"但显然./configure只能在Linux机器上使用,而且库通常没有在Windows上编译的指令(尽管它们支持Windows) ,他们不提供说明).
例如,库wxSVG表示它可以在Windows上运行,但是当我下载它时,我没有看到任何在Windows上编译的指令,我只有Linux文件用于配置它.
我最近遇到了严格的别名规则,但是我无法理解如何在void *不违反规则的情况下执行类型惩罚.
我知道这违反了规则:
int x = 0xDEADBEEF;
short *y = (short *)&x;
*y = 42;
int z = x;
Run Code Online (Sandbox Code Playgroud)
而且我知道我可以安全地使用C99中的联合进行类型惩罚:
union{
int x;
short y;
} data;
data.x = 0xDEADBEEF;
data.y = 42;
int z = data.x;
Run Code Online (Sandbox Code Playgroud)
但是如何void *在C99中安全地执行打字?以下是正确的:
int x = 0xDEADBEEF;
void * helper = (void *)&x;
short *y = (short *)helper;
*y = 42;
int z = x;
Run Code Online (Sandbox Code Playgroud)
我怀疑代码仍然会破坏严格的别名规则,因为变量x地址的内存可以由两者修改x并且可以解除引用y.
如果未定义类型 - 惩罚void *,那么void * …
我正在学习如何在我的Linux模块中使用sysfs,但我最难找到有关这些主题的当前文档.我一直在使用的Linux设备驱动程序第3版书似乎在这个领域相当过时(例如,class_device在当前的Linux版本中,结构似乎完全消失了).
我只是试图在我的模块的相应sysfs类下获得一个属性,这将允许我从内核空间读取模块变量的值.
在我的代码中,我创建了一个类,允许udev在/ dev/foo为我的模块创建一个设备节点:
dev_t foo_dev;
alloc_chrdev_region(&foo_dev, 0, 1, "bar");
struct class *bar = class_create(THIS_MODULE, "bar");
device_create(bar, NULL, foo_dev, NULL, "foo");
struct cdev foo_dev_file;
cdev_init(&foo_dev_file, &fops); /* fops defined earlier */
cdev_add(&foo_dev_file, foo_dev, 1);
Run Code Online (Sandbox Code Playgroud)
当我插入模块时,我得到了一个sysfs类目录,并在/ sys/class/bar/foo /中填充了一些默认属性.如何创建显示在此新目录下的属性?
我相信我的概念非常好 - 创建属性结构,定义sysfs_ops函数等 - 我的问题是我不知道使用哪个特定的内核结构(class_attribute?),也不知道如何使这些属性出现在右边sysfs目录.
有人会指点我的教程或文章详细介绍当前Linux内核的过程吗?
我正在使用x86 CentOS 6.3(内核v2.6.32)系统.
我将以下函数编译成一个简单的字符驱动程序模块作为实验,以了解Linux内核如何对浮点运算做出反应.
static unsigned floatstuff(void){
float x = 3.14;
x *= 2.5;
return x;
}
...
printk(KERN_INFO "x: %u", x);
Run Code Online (Sandbox Code Playgroud)
编译的代码(这是没有预料到的)所以我插入了模块并检查了日志dmesg.日志显示:x: 7.
这看起来很奇怪; 我以为你不能在Linux内核中执行浮点运算 - 除了一些例外kernel_fpu_begin().模块是如何执行浮点运算的?
这是因为我在x86处理器上吗?
我知道如果你执行GCC:
gcc -O3 -O2 foo.c
Run Code Online (Sandbox Code Playgroud)
GCC将使用传递的最后一个优化标志(在本例中O2).但是,这对所有旗帜都是如此吗?例如,如果我像这样执行GCC:
gcc -mno-sse -msse bar.c
Run Code Online (Sandbox Code Playgroud)
它会支持SSE,因为那是传递的最后一个标志,还是会导致未定义的行为?我最初的实验似乎表明它将支持SSE,但我不确定这是否适用于所有情况.
在C99标准的第7.18.1.1节第1段中:
typedef名称
intN_t指定有符号整数类型,其宽度为N,无填充位和二进制补码表示.
根据C99标准,精确宽度有符号整数类型需要具有二进制补码表示.这意味着,例如,int8_t具有最小值-128而不是1的补码最小值-127.
第6.2.6.2节第2段允许实现决定是将符号位解释为符号和幅度,二进制补码还是一个补码:
如果符号位为1,则应以下列方式之一修改该值:
- 符号位0的相应值被否定(符号和幅度);
- 符号位的值为 - (2 N)(二进制补码);
- 符号位的值为 - (2 N - 1)(1'补码).
方法之间的不同之处很重要,因为二进制补码(-128)中的整数的最小值可能超出了补码(-127to 127)中可表示的值的范围.
假设一个实现将int类型定义为具有ones' complement表示,而int16_t类型具有two's complementC99标准保证的表示.
int16_t foo = -32768;
int bar = foo;
Run Code Online (Sandbox Code Playgroud)
在这种情况下,转换 …