我正在尝试学习汇编(所以忍受我),我在这一行得到了一个编译错误:
mov byte [t_last], [t_cur]
Run Code Online (Sandbox Code Playgroud)
错误是
error: invalid combination of opcode and operands
Run Code Online (Sandbox Code Playgroud)
我怀疑这个错误的原因只是因为一个mov指令不可能在两个内存地址之间移动,但是半小时的谷歌搜索并且我无法确认这一点 - 是这样的吗?
另外,假设我是对的,这意味着我需要使用寄存器作为复制内存的中间点:
mov cl, [t_cur]
mov [t_last], cl
Run Code Online (Sandbox Code Playgroud)
什么是推荐使用的寄存器(或者我应该使用堆栈)?
在代码中使用printf
和wprintf
一起使用时遇到问题.如果首先打印常规字符串,则wprintf
不起作用.如果我wprintf
先使用则printf
不起作用.
#include <stdio.h>
#include <wchar.h>
#include <stdlib.h>
#include <locale.h>
int main()
{
setlocale(LC_ALL,"");
printf("No printing!\n");
wprintf(L"Printing!\n");
wprintf(L"Wide char\n");
printf("ASCII\n");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:
No printing!
ASCII
Run Code Online (Sandbox Code Playgroud)
而
#include <stdio.h>
#include <wchar.h>
#include <stdlib.h>
#include <locale.h>
int main()
{
setlocale(LC_ALL,"");
wprintf(L"Printing!\n");
printf("No printing!\n");
wprintf(L"Wide char\n");
printf("ASCII\n");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:
Printing!
Wide char
Run Code Online (Sandbox Code Playgroud)
我在64位Linux 3.0上使用gcc(GCC)4.6.1 20110819和glibc 2.14.
我知道我们可以使用二进制加法器的逻辑Sum = a XOR b
和Carry = a AND b
我也有一个解决方案:
int add(int a, int b)
{
if(b == 0)
return sum;
sum = a ^ b;
carry = (a & b) << 1;
return add(sum,carry);
}
Run Code Online (Sandbox Code Playgroud)
我在这里不明白的是为什么在每次递归期间进位位移位或乘以2?
我有一个只写数据的脚本stdout
.我需要为多个文件运行它并为每个输入文件生成不同的输出文件,我想知道如何使用find -exec
它.所以我基本上尝试了几种变体(我cat
为了可测试性而替换了脚本):
find * -type f -exec cat "{}" > "{}.stdout" \;
Run Code Online (Sandbox Code Playgroud)
但由于所有数据都被写入一个字面命名的文件,因此无法使其正常工作{}.stdout
.
最终,我可以使用它:
find * -type f -exec sh -c "cat {} > {}.stdout" \;
Run Code Online (Sandbox Code Playgroud)
但是,虽然这个最新的形式适用cat
,我的脚本需要通过几个初始化脚本加载环境变量,因此我最终得到:
find * -type f -exec sh -c "initscript1; initscript2; ...; myscript {} > {}.stdout" \;
Run Code Online (Sandbox Code Playgroud)
这似乎是浪费,因为我已经在我当前的shell中初始化了所有内容.
有没有更好的方法来做到这一点find
?欢迎其他单行.
我理解int16_t
或int32_t
在C中的方式是它们在您的计算机上分别被命名为16位和32位数字.我相信当你需要保证数字为16或32位时你会使用这些,因为不同的系统并不总是代表int
32位或short
16位(这个假设是正确的吗?当我在网上看时,我找到了混合的答案.) .
我的问题是当我要求它们实际上是16位或32位或其他什么时,我将如何使用一个函数scanf
来获取来自具有int16_t
或者int32_t
或任何其他类型定义数字类型的用户的输入?有某种特殊的字符串修饰符吗?通常情况下,如果我想int
从一个用户那里得到一个没有关心它实际表示多大的用户,我会写这样的东西
scanf("%d", &int);
Run Code Online (Sandbox Code Playgroud)
这是有效的,如果我传入一个,int32_t
但我认为它只是因为int
我的系统是32位,它没有特别给我一个32位数,而只是给了我一个int
.我如何获得保证为32位的数字?我查看了这个字符串修饰符和其他一些地方的页面,但没有提到这些类型定义的数字类型.
编辑:自从收到我的问题的答案后,我做了一些谷歌搜索并找到了这个.我将它包括在下面以供参考.
uppercase hexadecimal printf format for uintptr_t
#define SCNd16 "d"
decimal scanf format for int16_t
#define SCNd32 "ld"
decimal scanf format for int32_t
#define SCNd8 "hhd"
decimal scanf format for int8_t
#define SCNdFAST16 "d"
decimal scanf format for int_fast16_t
#define SCNdFAST32 "ld"
decimal scanf format …
Run Code Online (Sandbox Code Playgroud) 我发现了一个影响我工作中的多个单元测试的问题,这种问题仅在使用 valgrind 运行单元测试时才会发生,因为对于相同的输入,从 std::cos 和 std::sin 返回的值是不同的,具体取决于是否单元测试是独立运行的,而不是在 valgrind 下运行。
这个问题似乎只发生在某些特定的输入上,因为许多单元测试都通过了相同的代码。
这是一个最低限度可重现的示例(稍微恶化,以便我的编译器不会优化任何逻辑):
#include <complex>
#include <iomanip>
#include <iostream>
int main()
{
std::complex<long double> input(0,0), output(0,0);
input = std::complex<long double>(39.21460183660255L, -40);
std::cout << "input: " << std::setprecision(20) << input << std::endl;
output = std::cos(input);
std::cout << "output: " << std::setprecision(20) << output << std::endl;
if (std::abs(output) < 5.0)
{
std::cout << "TEST FAIL" << std::endl;
return 1;
}
std::cout << "TEST PASS" << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
正常运行时输出:
input: (39.21460183660254728,-40)
output: (6505830161375283.1118,117512680740825220.91) …
Run Code Online (Sandbox Code Playgroud) 为了简化问题,我想说我想a / (b - c)
在float
s 上计算表达式.
为了确保结果是有意义的,我可以检查b
和c
是相等的:
float EPS = std::numeric_limits<float>::epsilon();
if ((b - c) > EPS || (c - b) > EPS)
{
return a / (b - c);
}
Run Code Online (Sandbox Code Playgroud)
但是我的测试表明,如果可能的话,不能保证有意义的结果,也不能不提供结果.
a = 1.0f;
b = 0.00000003f;
c = 0.00000002f;
Run Code Online (Sandbox Code Playgroud)
结果:不满足if条件,但表达式将生成正确的结果100000008(与浮点数的精度相同).
a = 1e33f;
b = 0.000003;
c = 0.000002;
Run Code Online (Sandbox Code Playgroud)
结果:满足if条件,但表达式不会产生有意义的结果+1.#INF00
.
我发现检查结果更可靠,而不是参数:
const float INF = numeric_limits<float>::infinity();
float x = a / (b - c); …
Run Code Online (Sandbox Code Playgroud) 是否有可能将float
s从大端转换为小端?我有一个来自PowerPC平台的大端值,我通过TCP发送到Windows进程(小端).这个值是a float
,但是当我memcpy
将值转换为Win32 float类型然后调用_byteswap_ulong
该值时,我总是得到0.0000?
我究竟做错了什么?
我有很多代码对无符号整数执行按位运算.我编写了我的代码,假设这些操作是在固定宽度的整数上,没有任何填充位.例如,32位无符号整数的数组,其中所有32位可用于每个整数.
我希望让我的代码更具可移植性,并且我专注于确保我符合C89(在这种情况下).我遇到的一个问题是填充整数.拿这个极端的例子,取自GMP手册:
然而,在Cray矢量系统上,可以注意到short和int总是以8个字节存储(并且sizeof指示),但仅使用32或46位.指甲功能可以通过传递例如8*sizeof(int)-INT_BIT来解决这个问题.
我也在其他地方读过这种类型的填充.我昨晚实际上在SO上读了一篇文章(请原谅我,我没有链接,我将引用类似记忆的内容),如果你有一个带有60个可用位的双,另外4个可以用于填充和那些填充位可以用于某些内部目的,因此它们不能被修改.
因此,假设我的代码是在一个平台上编译的,其中unsigned int类型的大小为4个字节,每个字节为8位,但最重要的2位是填充位.在这种情况下UINT_MAX会是0x3FFFFFFF(1073741823)吗?
#include <stdio.h>
#include <stdlib.h>
/* padding bits represented by underscores */
int main( int argc, char **argv )
{
unsigned int a = 0x2AAAAAAA; /* __101010101010101010101010101010 */
unsigned int b = 0x15555555; /* __010101010101010101010101010101 */
unsigned int c = a ^ b; /* ?? __111111111111111111111111111111 */
unsigned int d = c << 5; /* ?? __111111111111111111111111100000 */
unsigned int e = d >> 5; /* ?? __000001111111111111111111111111 */
printf( "a: …
Run Code Online (Sandbox Code Playgroud) 是memcpy()
通常速度比strcpy()
(上最真实的平台)?(我假设字符串的大小是已知的.)
如果我正确地记得i386汇编程序,则会有loop
指令复制给定数量的字节或单词.所以它是最快的方式,而strcpy()
i386汇编程序实现将'\0'
在一个简单的循环中使用手动检查.
所以我觉得在x86上memcpy()
要快于strcpy()
.
其他架构是什么?
c ×4
c++ ×2
x86 ×2
assembly ×1
endianness ×1
epsilon ×1
gcc ×1
instructions ×1
linux ×1
memcpy ×1
mov ×1
padding ×1
performance ×1
precision ×1
scanf ×1
std ×1
strcpy ×1
unix ×1
user-input ×1
valgrind ×1