小编RuR*_*uRo的帖子

为什么 scanf 失败时不恢复字符?

我知道scanf(和系列)返回它成功读取的参数数量。我还知道,如果失败,输入将保持不变,因此您可以执行以下操作:

printf("%s", "Plese input a string or a float.\n");
float f;
char s[128];
if(scanf("%f", &f) == 1) {
    //do something to respond to user answering with a float. (1)
} else if(scanf("%127s", s)) {
    //do something to process the string. (2)
}
Run Code Online (Sandbox Code Playgroud)

事实证明这scanf 确实扰乱了输入。我希望 scanf 尝试读取任何匹配的内容<float here>,并且在失败的情况下不执行任何操作,但相反发生的情况是scanf吃掉输入,直到它认为适合停止的任何点。

例如:如果我输入1.2,我最终会按预期(1)进入分支。f = 1.2

如果我输入的text结果符合预期,我最终会得到(2)s = "text"

但是,如果输入是normal结果,我最终会得到(2)没有任何额外的用户输入和s = "rmal" …

c scanf

5
推荐指数
2
解决办法
322
查看次数

为什么左侧的"取消引用"和"运营商地址"?

在C(以及一些其他类C语言)中,我们有2个一元运算符用于处理指针:dereference运算符(*)和'address of'运算符(&).他们留下一元运算符,它引入了一个不确定性的操作顺序,例如:

*ptr->field
Run Code Online (Sandbox Code Playgroud)

要么

*arr[id]
Run Code Online (Sandbox Code Playgroud)

操作的顺序严格标准定义的,而是从一个人的角度来看,这是令人困惑的.如果*操作员是一个正确的一元操作员,那么订单将是显而易见的,并且不需要额外的括号:

ptr*->field vs ptr->field*
Run Code Online (Sandbox Code Playgroud)

arr*[id] vs arr[id]*
Run Code Online (Sandbox Code Playgroud)

因此,运营商为什么要保持一元而不是正确,这是有充分理由的.想到的一件事是类型的声明.左运营附近逗留类型名称(char *aVS char a*),但也有类型声明,这已经打破了这一规则,何必(char a[num],char (*a)(char),等).

显然,这种方法也有一些问题,比如

 val*=2
Run Code Online (Sandbox Code Playgroud)

这将是一个*=简短的手val = val * 2或取消引用和分配val* = 2.然而,这可以通过在解除引用的情况下在令牌*=令牌之间需要空白空间来容易地解决.再一次,没有任何开创性的,因为有这样一个规则的先例(- -avs --a).

那么为什么他们离开而不是正确的运营商?

编辑:我想指出,我问过这个问题,因为C的许多怪问题都有有趣的解释,为什么它们是这样的,就像运算符存在->或类型声明或索引从等等.原因可能不再有效,但我认为它们仍然很有趣.

c syntax pointers operator-precedence dereference

5
推荐指数
1
解决办法
337
查看次数

用于双重否定的奇怪的SSE汇编程序指令

GCC和Clang编译器似乎采用了一些黑暗魔法.该C代码只是否定了双重的价值,但汇编指令涉及逐位XOR和指令指针.有人可以解释发生了什么,为什么它是一个最佳解决方案.谢谢.

test.c的内容:

void function(double *a, double *b) {
    *a = -(*b); // This line.
}
Run Code Online (Sandbox Code Playgroud)

生成的汇编程序指令:

(gcc)
0000000000000000 <function>:
 0: f2 0f 10 06             movsd  xmm0,QWORD PTR [rsi]
 4: 66 0f 57 05 00 00 00    xorpd  xmm0,XMMWORD PTR [rip+0x0]        # c <function+0xc>
 b: 00 
 c: f2 0f 11 07             movsd  QWORD PTR [rdi],xmm0
10: c3                      ret 
Run Code Online (Sandbox Code Playgroud)
(clang)
0000000000000000 <function>:
 0: f2 0f 10 06             movsd  xmm0,QWORD PTR [rsi]
 4: 0f 57 05 00 00 …
Run Code Online (Sandbox Code Playgroud)

assembly gcc sse x86-64 magic-numbers

0
推荐指数
1
解决办法
174
查看次数