小编Rob*_*rtS的帖子

为什么快速整数类型比其他整数类型快?

在 ISO/IEC 9899:2018 (C18) 中,它在 7.20.1.3 下说明:

7.20.1.3 最快的最小宽度整数类型

1 以下每种类型都指定了一个整数类型,在所有至少具有指定宽度的整数类型中,该类型通常是最快的268)

2 typedef 名称int_fastN_t指定宽度至少为 Nuint_fastN_t的最快有符号整数类型。 typedef 名称指定宽度至少为 N的最快无符号整数类型。

3 需要以下类型:

int_fast8_t, int_fast16_t, int_fast32_t, int_fast64_t, uint_fast8_t, uint_fast16_t, uint_fast32_t,uint_fast64_t

此表格的所有其他类型都是可选的。


268)不保证指定的类型在所有用途中都是最快的;如果实现没有明确的理由选择一种类型而不是另一种,它只会选择一些满足符号和宽度要求的整数类型。


但是没有说明为什么这些“快速”整数类型更快。

  • 为什么这些快速整数类型比其他整数类型快?

我用 C++ 标记了这个问题,因为在 C++17 的头文件中也可以使用快速整数类型cstdint。不幸的是,在 ISO/IEC 14882:2017 (C++17) 中没有关于它们的解释的这样的部分;我已经在问题正文中以其他方式实施了该部分。


信息:在 C 中,它们在stdint.h.

c c++ int performance types

115
推荐指数
3
解决办法
8363
查看次数

我可以使用 NULL 代替 0 的值吗?

我可以使用NULL指针代替 的值0吗?

或者这样做有什么问题吗?


比如,例如:

int i = NULL;
Run Code Online (Sandbox Code Playgroud)

作为替代:

int i = 0;
Run Code Online (Sandbox Code Playgroud)

作为实验,我编译了以下代码:

#include <stdio.h>

int main(void)
{
    int i = NULL;
    printf("%d",i);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出:

0
Run Code Online (Sandbox Code Playgroud)

事实上,它给了我这个警告,这本身是完全正确的:

warning: initialization makes integer from pointer without a cast [-Wint-conversion] 
Run Code Online (Sandbox Code Playgroud)

但结果仍然是等价的。


  • 我是否会因此而进入“未定义行为”?
  • 可以这样使用NULL吗?
  • NULL在算术表达式中用作数值有什么问题吗?
  • 对于这种情况,C++ 中的结果和行为是什么?

我已阅读的答案是什么NULL之间的区别,“\ 0”和0大约之间的区别是什么NULL\0以及0是的,但我没有从那里简洁的信息,如果是很允许的,也是正确的使用NULL作为在赋值和其他算术运算中使用的值。

c c++ null pointers language-lawyer

77
推荐指数
7
解决办法
7224
查看次数

C 和 C++ 中的 (...) 是什么?

的用途之一...是在 C 和 C++ 中表示可变参数实体。

它叫什么名字?

以这种方式使用时,它是否归类为运算符或其他东西?

关于 的任何其他细节...

编辑: 我知道.... 我问的是它的名称和分类,我希望它在 C 和 C++ 中都相似。

c c++ terminology ellipsis variadic

30
推荐指数
3
解决办法
4174
查看次数

在可执行程序的上下文中,“二进制文件”和“可执行文件”之间的区别在哪里?

我经常看到术语“二进制”和“可执行文件”似乎可以互换用于同一事物。

不是用两个术语来描述完全相同的事物吗?编译后的可执行输出程序,我可以在终端上运行吗?

什么加强了我的假设,这两个东西应该是相同的bin,在应用程序的安装文件夹中提供一个文件夹(“bin”作为“binaries”的缩写)是一种常见的做法,以存储可执行文件用户可以运行的文件。


我已经阅读了ndisasm 手册中提到的二进制文件和可执行文件什么区别?但问题和他们的答案更侧重于 Clang 和 ndasm 各自的环境。

我还在软件工程论坛上阅读了https://softwareengineering.stackexchange.com/questions/121224/what-are-binaries的问题和答案,但这里也没有区分可执行文件和二进制文件;只有一般的“二进制”一词可以指代:

但是,在Computing 中, Binary 指的是:

[来源:https : //softwareengineering.stackexchange.com/a/121235/349225]

其中,在编译过程的输出程序的上下文中,二进制文件与可执行文件相同,以及:

的二进制文件被用作产生一组文件的编译后基本上对象代码运行的机器上。(和虚拟机/运行时在 Java/.NET 的情况下)

[来源:https : //softwareengineering.stackexchange.com/a/121234/349225 ]

在那里它被称为相同。


  • 在可执行程序的上下文中,“二进制文件”和“可执行文件”有什么区别?
  • 区别在哪里?

language-agnostic executable terminology binaryfiles

14
推荐指数
2
解决办法
7686
查看次数

AddressSanitizer 中的“影子字节”是什么,我应该如何解释它们?

我正在调试一个 C 程序,当它发现问题时,我对 AddressSanitizer 输出的下半部分感到非常困惑。例如,让我们使用它:

==33184==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000005 at pc 0x55f312fe2509 bp 0x7ffc99f5f5c0 sp 0x7ffc99f5f5b0
WRITE of size 1 at 0x602000000005 thread T0
    #0 0x55f312fe2508 in main /home/user/c/friends/main.c:20
    #1 0x7fa5ea0e9b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
    #2 0x55f312fe21c9 in _start (/home/user/c/friends/cmake-build-debug/friends+0x11c9)

0x602000000005 is located 11 bytes to the left of 5-byte region [0x602000000010,0x602000000015)
allocated by thread T0 here:
    #0 0x7fa5eb2b8b40 in __interceptor_malloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xdeb40)
    #1 0x55f312fe23f4 in main /home/user/c/friends/main.c:18
    #2 0x7fa5ea0e9b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)

SUMMARY: AddressSanitizer: heap-buffer-overflow /home/user/c/friends/main.c:20 in …
Run Code Online (Sandbox Code Playgroud)

c memory debugging address-sanitizer

13
推荐指数
1
解决办法
1993
查看次数

指向指针衰减的数组是否更改为指针对象?

int a[] = {1, 2 ,3};
Run Code Online (Sandbox Code Playgroud)

我知道数组名称被转换为指针。一个经常使用的术语是它们衰减为指针。

然而对我来说, apointer是一个内存区域,它保存着另一个内存区域的地址,所以:

int *p = a;
Run Code Online (Sandbox Code Playgroud)

可以这样画:

-----              -----
  p    --------->  a[0].  .....
-----              -----
 0x1                0x9
Run Code Online (Sandbox Code Playgroud)

a它本身并不是指向另一个内存区域,它是内存区域本身。因此,当编译器将其转换为指针时,是将它(如p)保存在内存中的某处还是隐式转换?

c memory arrays pointers language-lawyer

13
推荐指数
2
解决办法
309
查看次数

标头 ncurses.h 和curses.h 之间的区别

curses 库的标头<ncurses.h>和变体之间有什么区别?<curses.h>


为什么我应该更喜欢

#include <ncurses.h>

代替

#include <curses.h>


我已经在我的 Linux 发行版中搜索了差异。在我的实现(Linux Ubuntu Pengolin)中,<ncurses.h><curses.h>. 所以没有区别。

但为什么两个名字却分开了呢?


不幸的是,这个问题的答案What's the Difference between -lcurses and -lncurses when compiling C using ncurses lib? 没有解决我的担忧,因为他们更专注于在调用编译器时添加相应的标志,并且不解释一般的差异。

c c++ curses ncurses difference

10
推荐指数
1
解决办法
7165
查看次数

为什么从 main() 返回 NULL?

我有时会看到编码器在 C 和 C++ 程序中NULL用作返回值main(),例如:

#include <stdio.h>

int main()
{
    printf("HelloWorld!");

    return NULL;
} 
Run Code Online (Sandbox Code Playgroud)

当我用 gcc 编译这个`代码时,我收到以下警告:

警告:返回从指针生成整数而不进行强制转换 [-Wint-conversion]

这是合理的,因为宏NULL应扩展为(void*) 0并且 main 的返回值应为类型int

当我制作一个简短的 C++ 程序时:

#include <iostream>
using namespace std;

int main()
{
    cout << "HelloWorld!";

    return NULL;
}
Run Code Online (Sandbox Code Playgroud)

并用 g++ 编译它,我确实得到了一个等效的警告:

警告:从 NULL [-Wconversion-null] 转换为非指针类型“int”

但是为什么它们在抛出警告时NULL用作返回值main()?这只是糟糕的编码风格吗?


  • 尽管有警告,但使用NULL而不是0作为返回值的原因是什么main()
  • 如果这合适与否,它是由实现定义的,如果是这样,为什么任何实现都想要取回指针值?

c c++ null return return-value

10
推荐指数
2
解决办法
1037
查看次数

在 C 中从末尾访问数组?

最近,我注意到,在C,有一个重要区别array,并&array以下声明:

char array[] = {4, 8, 15, 16, 23, 42};
Run Code Online (Sandbox Code Playgroud)

前者是一个指向 char 的指针,而后者是一个指向 6 个字符的数组的指针。另外值得注意的是,写作a[b]*(a + b). 确实,您可以编写2[array]并根据标准完美运行。

所以我们可以利用这些信息来写:

char last_element = (&array)[1][-1];
Run Code Online (Sandbox Code Playgroud)

&array具有 6 个字符的大小,因此(&array)[1])是指向位于数组后面的字符的指针。通过查看,[-1]我正在访问最后一个元素。

有了这个,我可以例如交换整个数组:

void swap(char *a, char *b) { *a ^= *b; *b ^= *a; *a ^= *b; }

int main() {
    char u[] = {1,2,3,4,5,6,7,8,9,10};

    for (int i = 0; i < sizeof(u) / 2; i++) …
Run Code Online (Sandbox Code Playgroud)

c arrays pointers language-lawyer

10
推荐指数
1
解决办法
351
查看次数

空指针常量可以是任何计算为 0 的整数常量表达式吗?

标准说:

"一个值为 0 的整数常量表达式,或这样一个转换为 type 的表达式void*,称为空指针常量.67) 如果将空指针常量转换为指针类型,则保证得到的指针称为空指针比较不等于指向任何对象或函数的指针。”


" 67) 宏 NULL 在 stddef.h(和其他头文件)中定义为空指针常量;见 7.19。 "

来源:ISO/IEC 9899:2018 (C18),第 6.2.3.2/3 节“指针”。

最常见的空指针常量当然是最常见的,0并且(void*) 0被大多数实现用作空指针常量,但作为标准要求 - 值为 0 的整数常量表达式,或这样的表达式转换为类型void*” -空指针常量应也可以是以下任何一种:

  1. 1 * 0
  2. 0 * 0
  3. 0 - 0
  4. 25 - 25
  5. (-4) + (4)
  6. (0 * ((0 * 25) * 3)
  7. (0) * (-100)

就像他们前面有(void*), fe(void*) (1 * 0) …

c null pointers language-lawyer constant-expression

10
推荐指数
1
解决办法
225
查看次数