标签: c

C的隐藏功能

我知道所有C编译器实现背后都有一个标准,所以应该没有隐藏的功能.尽管如此,我确信所有C开发人员都有他们一直使用的隐藏/秘密技巧.

c hidden-features

141
推荐指数
33
解决办法
8万
查看次数

我如何使用函数指针数组?

我应该如何在C中使用函数指针数组?

我该如何初始化它们?

c initialization function-pointers

141
推荐指数
5
解决办法
24万
查看次数

我该如何打印off_t和size_t等类型?

我正在尝试打印类似off_tsize_t.什么是正确的占位符printf() 是可移植的

或者是否有完全不同的方式来打印这些变量?

c portability format-specifiers

141
推荐指数
3
解决办法
13万
查看次数

GCC的标准替代## __ VA_ARGS__技巧?

C99中的可变参数宏存在一个众所周知的 空args 问题.

例:

#define FOO(...)       printf(__VA_ARGS__)
#define BAR(fmt, ...)  printf(fmt, __VA_ARGS__)

FOO("this works fine");
BAR("this breaks!");
Run Code Online (Sandbox Code Playgroud)

BAR()根据C99标准,上述用途确实不正确,因为它将扩展到:

printf("this breaks!",);
Run Code Online (Sandbox Code Playgroud)

请注意尾随逗号 - 不可行.

一些编译器(例如:Visual Studio 2010)将悄然摆脱那个尾随的逗号.其他编译器(例如:GCC)支持放在##前面__VA_ARGS__,如下所示:

#define BAR(fmt, ...)  printf(fmt, ##__VA_ARGS__)
Run Code Online (Sandbox Code Playgroud)

但有没有符合标准的方法来获得这种行为?也许使用多个宏?

现在,该##版本似乎得到了相当好的支持(至少在我的平台上),但我真的更喜欢使用符合标准的解决方案.

先发制人:我知道我可以写一个小功能.我正在尝试使用宏来做到这一点.

编辑:以下是我想要使用BAR()的一个例子(虽然简单):

#define BAR(fmt, ...)  printf(fmt "\n", ##__VA_ARGS__)

BAR("here is a log message");
BAR("here is a log message with a param: %d", 42);
Run Code Online (Sandbox Code Playgroud)

这会自动为我的BAR()日志记录语句添加换行符,假设fmt它始终是双引号C字符串.它不会将换行符打印为单独的printf(),如果日志记录是行缓冲的并且异步来自多个源,则这是有利的.

c c99 c-preprocessor variadic-macros

141
推荐指数
6
解决办法
7万
查看次数

指针澄清的指针

我正在按照本教程关于指针如何工作.

让我引用相关段落:


    int i = 5, j = 6, k = 7;
    int *ip1 = &i, *ip2 = &j;
Run Code Online (Sandbox Code Playgroud)

现在我们可以设置

    int **ipp = &ip1;
Run Code Online (Sandbox Code Playgroud)

ipp指向ip1哪些点i.*ippis ip1,and **ippis i,or 5.我们可以用我们熟悉的盒子和箭头符号来说明这种情况,如下所示:

在此输入图像描述

如果那时我们说

    *ipp = ip2;
Run Code Online (Sandbox Code Playgroud)

我们已经改变了指向ipp(即ip1)的指针以包含一个副本ip2,因此it(ip1)现在指向j:

在此输入图像描述


我的问题是:为什么在第二张图片中ipp仍然指向ip1但不是ip2

c pointers

141
推荐指数
9
解决办法
1万
查看次数

我如何制作一个不会被优化掉的无限空循环?

C11 标准似乎暗示不应优化带有常量控制表达式的迭代语句。我从这个答案中得到了我的建议,它特别引用了标准草案中的第 6.8.5 节:

其控制表达式不是常量表达式的迭代语句......可能会被实现假定为终止。

在该答案中,它提到while(1) ;不应进行优化之类的循环。

那么……为什么 Clang/LLVM 优化了下面的循环(用 编译cc -O2 -std=c11 test.c -o test)?

#include <stdio.h>

static void die() {
    while(1)
        ;
}

int main() {
    printf("begin\n");
    die();
    printf("unreachable\n");
}
Run Code Online (Sandbox Code Playgroud)

在我的机器上,这会打印出begin,然后在非法指令ud2放置在 之后的陷阱die()上崩溃在 Godbolt 上,我们可以看到调用puts.

让 Clang 输出无限循环是一项非常困难的任务-O2- 虽然我可以反复测试一个volatile变量,但这涉及到我不想要的内存读取。如果我做这样的事情:

#include <stdio.h>

static void die() {
    while(1)
        ;
}

int main() {
    printf("begin\n");
    volatile int x …
Run Code Online (Sandbox Code Playgroud)

c clang compiler-optimization language-lawyer

141
推荐指数
6
解决办法
3万
查看次数

array [100] = {0}如何将整个数组设置为0?

编译器如何填充值char array[100] = {0};?它背后的魔力是什么?

我想知道内部编译器如何初始化.

c c++ compiler-construction

140
推荐指数
4
解决办法
23万
查看次数

如何在C中找到可执行文件的位置?

在C/C++中是否有办法找到当前执行程序的位置(完整路径)?

(问题argv[0]在于它没有给出完整的路径.)

c c++ unix linux path

140
推荐指数
6
解决办法
7万
查看次数

if-else块中'if(0)'块的目的是什么?

我的问题是关于我在主题中提到的那条线,我可以在生产代码中的许多地方看到.

整体代码如下所示:

if (0) {
    // Empty braces
} else if (some_fn_call()) {
    // actual code
} else if (some_other_fn_call()) {
    // another actual code
    ...
} else {
    // default case
}
Run Code Online (Sandbox Code Playgroud)

其他分支与我的问题无关.我想知道放在if (0)这里的含义是什么.大括号是空的,所以我认为它不应该评论一些代码块.它会强制编译器进行一些优化还是意图不同?

我试图在SO和互联网上搜索这个明确的案例,但没有成功.关于JavaScript有类似的问题,但不是C.还有另一个问题,当在`if`条件中分配零时会发生什么?,但它讨论了对变量的零赋值,而不是'if(0)'用法本身.

c if-statement

140
推荐指数
11
解决办法
1万
查看次数

写入.txt文件?

如何将一小段文本写入.txt文件?我一直在谷歌搜索超过3-4个小时,但无法找到如何做到这一点.

fwrite(); 有这么多论点,我不知道如何使用它.

当您只想为文件写一个名字和几个数字时,最简单的功能是什么.txt

编辑:添加了一段我的代码.

    char name;
    int  number;
    FILE *f;
    f = fopen("contacts.pcl", "a");

    printf("\nNew contact name: ");
    scanf("%s", &name);
    printf("New contact number: ");
    scanf("%i", &number);


    fprintf(f, "%c\n[ %d ]\n\n", name, number);
    fclose(f);
Run Code Online (Sandbox Code Playgroud)

c linux

139
推荐指数
2
解决办法
56万
查看次数