昨天,有人给我看了这个代码:
#include <stdio.h>
int main(void)
{
unsigned long foo = 506097522914230528;
for (int i = 0; i < sizeof(unsigned long); ++i)
printf("%u ", *(((unsigned char *) &foo) + i));
putchar('\n');
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这导致:
0 1 2 3 4 5 6 7
Run Code Online (Sandbox Code Playgroud)
我很困惑,主要是for
循环中的行。据我所知,似乎&foo
是被强制转换为 anunsigned char *
然后被i
. 我觉得*(((unsigned char *) &foo) + i)
是一个更详细的书写方式((unsigned char *) &foo)[i]
,但是这使得它看起来像foo
,一个unsigned long
被索引。如果是这样,为什么?循环的其余部分似乎是典型的打印数组的所有元素,所以一切似乎都表明这是真的。演员unsigned char *
阵容让我更加困惑。我试图寻找有关转换的整数类型,以char *
对谷歌而言,但我的研究得到了一些后无用的搜索结果停留约铸造int …
c pointers casting char-pointer implementation-defined-behavior
因为我知道 an 的每个元素enum
都有自己的整数值,所以我尝试了以下方法:
enum Foo {
Red = 0,
Blue = 1
};
int main(void) {
enum Foo bar = 2;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
它......有效。int
我进一步观察,我认为它具有与(我在 UB 之后开始体验 UB )相同的最小和最大限制INT_MAX
。那么,a 不就enum
比一组#define
s 更好吗?不过,我在这里也很可能是错的。
我不确定我是否在这里问菜鸟问题,但我就在这里。我也搜索了很多类似的问题,但一无所获。
所以,我知道如何mmap
工作brk
,无论您输入的长度如何,它都会将其四舍五入到最近的页面边界。我也知道malloc
使用brk
/sbrk
或mmap
(至少在 Linux/Unix 系统上),但这提出了一个问题:是否malloc
也舍入到最接近的页面大小?对我来说,页面大小是 4096 字节,所以如果我想分配 16 字节malloc
,4096 字节......比我要求的要多得多。
所以我试图找出的大小zword
,并yword
当我偶然发现这是很有帮助的线程其中有各种规模的名单,但有一两件事让我感到困惑。它在编辑中说 atword
是 10 个字节,但这对我来说没有意义。一个字是两个字节,所以一个tword
字应该是 10 个字,也就是 20 个字节,不是吗?我发现更奇怪的是 anoword
确实是 8 个字/16 字节,所以 anoword
实际上比 a 大tword
。这种奇怪的命名选择有什么解释吗?
维基百科指出:
计算中的高级汇编程序是汇编语言的汇编程序,它合并了高级编程语言中的功能。
它接着说:
高级汇编程序通常提供直接将一对一汇编成低级机器代码的指令,就像在任何汇编程序中一样,以及诸如 IF、WHILE、REPEAT...UNTIL 和 FOR、宏和其他增强功能的控制语句。
最后,它指的是一些高级汇编程序:
较新的高级汇编程序是 Borland 的 TASM、NASM、Microsoft 的 MASM、IBM 的 HLASM(用于 z/Architecture 系统)、Alessandro Ghignola 的 Linoleum 和 Ziron。
其中,我只用过 NASM,但我能理解为什么它是一个高级汇编器;它具有结构、宏和一个非常广泛的预处理器。但是,当我看到 FASM 的 Wikipedia 页面时,它将 FASM 称为低级汇编程序,我并没有真正理解。FASM 不仅支持结构体和宏(我对预处理器了解不多),还支持汇编时的 if 语句。是否有任何其他规则指定汇编程序是高级还是低级?FASM 维基百科页面说它故意不支持许多命令行选项,但仅此一项就使其成为低级汇编程序吗?
如何使用 C 中的系统调用附加到文件的开头(而不是结尾)?
我已经阅读了 open() 的手册页。我没有找到任何允许我附加到文件开头的标志代码(类似于 O_APPEND)。
(澄清 - Linux 中的系统调用)
标题说明了一切。由于 C 没有异常,我不太确定如何处理错误。我考虑过两者的优点和缺点:
ABORTING:
基本上我的意思是返回一个错误代码(将在 .h 文件中声明,可能使用它自己的perror()
类似函数)并中止该函数,明显的优点是它可以帮助用户执行错误- 处理,但缺点是:
退出程序:
非常不言自明:一旦发现错误,将错误打印到stderr
并退出。这样做的优点是,如果错误消息足够详细,用户将很容易知道他们的代码出了什么问题并修复它,但主要缺点是用户将无法编写任何可以处理可能的错误的代码。错误,而必须更改代码本身(当您需要请求输入或类似的东西时,这会成为一个更大的问题,其中不正确的输入可能会产生数百万个可能的错误)。
你能告诉我x86汇编中ja
(如果高于则跳转)和jnbe
(如果不低于或等于则跳转)指令之间的区别吗?我什么时候使用它们?他们给我不同的结果吗?
c ×5
assembly ×3
nasm ×2
append ×1
brk ×1
casting ×1
char-pointer ×1
enums ×1
error-code ×1
fasm ×1
implementation-defined-behavior ×1
linux ×1
malloc ×1
mmap ×1
pointers ×1
system-calls ×1
text ×1
x86 ×1