Questions tagged «c»

C是用于系统编程(OS和嵌入式),库,游戏和跨平台的通用编程语言。该标记应与ISO 9899标准(除非另有说明,最新版本9899:2018中定义的有关C语言的一般问题)一起使用-还要使用c89,c99,c11等标记特定于版本的请求。C与C ++截然不同,在没有合理理由的情况下,不应将其与C ++标记结合使用。

9
C中的'\ 0'和printf()
在C的入门课程中,我了解到在存储字符串的同时,在字符串\0末尾存储了空字符。但是,如果我想打印一个字符串,该怎么办,printf("hello")尽管我发现它并没有以\0以下语句结尾 printf("%d", printf("hello")); Output: 5 但这似乎是不一致的,据我所知,像字符串这样的变量存储在主存储器中,我想在打印内容时也可能将其存储在主存储器中,那为什么会有区别呢?
21 c  printf  stdout  c-strings 

2
lambda宏如何创建lambda?
我在GitHub上找到了这段代码,但不太了解: #define lambda(ret_type, _body) ({ ret_type _ _body _; }) 然后: int (*max)(int, int) = lambda(int, (int x, int y) { return x > y ? x : y; }); int max_value = max(1, 2); // max_value is 2 内的下划线是什么#define?它如何返回函数指针?


3
static int arr [10]存储器地址始终以060结尾
我有一个看起来像这样的交流程序 main.c #include <stdio.h> #define SOME_VAR 10 static int heap[SOME_VAR]; int main(void) { printf("%p", heap); return 0; } 并在运行编译程序几次后输出 0x58aa7c49060 0x56555644060 0x2f8d1f8e060 0x92f58280060 0x59551c53060 0xd474ed6e060 0x767c4561060 0xf515aeda060 0xbe62367e060 为什么总是以060结尾?数组是否存储在堆中? 编辑:我在Linux上,并且我有ASLR。我用gcc编译了程序
17 c  arrays  memory 

1
为什么即使ASLR开启,__ libc_start_main的地址在GDB中也总是相同的?
Breakpoint 1, 0x00007ffff7de8060 in __libc_start_main () from /usr/lib/libc.so.6 (gdb) r The program being debugged has been started already. Start it from the beginning? (y or n) y Starting program: /home/firstlove/projects/org-ioslide/example/a.out Breakpoint 1, 0x00007ffff7de8060 in __libc_start_main () from /usr/lib/libc.so.6 (gdb) r The program being debugged has been started already. Start it …
16 c  linux  gdb  libc  aslr 


1
为什么np.dot不精确?(n维数组)
假设我们采用np.dot两个'float32'2D数组: res = np.dot(a, b) # see CASE 1 print(list(res[0])) # list shows more digits [-0.90448684, -1.1708503, 0.907136, 3.5594249, 1.1374011, -1.3826287] 数字。除了它们可以更改: 案例1:切片a np.random.seed(1) a = np.random.randn(9, 6).astype('float32') b = np.random.randn(6, 6).astype('float32') for i in range(1, len(a)): print(list(np.dot(a[:i], b)[0])) # full shape: (i, 6) [-0.9044868, -1.1708502, 0.90713596, 3.5594249, 1.1374012, -1.3826287] …
15 python  c  arrays  numpy  precision 

3
具有非常量指针和相同地址的const参数的指针的函数调用
我想编写一个函数,该函数输入一个数据数组并使用指针输出另一个数据数组。 我想知道如果两者都指向同一地址会产生什么结果src,dst因为我知道编译器可以针对const进行优化。它是未定义的行为吗?(我同时标记了C和C ++,因为我不确定答案是否可能会有所不同,并且我想了解两者。) void f(const char *src, char *dst) { dst[2] = src[0]; dst[1] = src[1]; dst[0] = src[2]; } int main() { char s[] = "123"; f(s,s); printf("%s\n", s); return 0; } 除了上述问题,如果删除const原始代码中的,是否定义明确?

5
为什么无效的语句在C语言中被视为合法?
如果这个问题很天真,请原谅。考虑以下程序: #include <stdio.h> int main() { int i = 1; i = i + 2; 5; i; printf("i: %d\n", i); } 在上面的例子中,陈述5;和i;似乎完全是多余的,但如果没有默认警告或错误的代码编译(但是,GCC则会引发warning: statement with no effect [-Wunused-value]警告时RAN -Wall)。它们对程序的其余部分没有影响,那么为什么首先将它们视为有效的语句?编译器会简单地忽略它们吗?允许这样的陈述有什么好处?
13 c 

5
比较一下布尔值
假设我有一组以uint16_t编码的标志flags。例如,AMAZING_FLAG = 0x02。现在,我有一个功能。此函数需要检查是否要更改标志,因为如果要更改标志,则需要写入闪存。那很贵。因此,我想要一张支票告诉我是否flags & AMAZING_FLAG等于doSet。这是第一个想法: setAmazingFlag(bool doSet) { if ((flags & AMAZING_FLAG) != (doSet ? AMAZING_FLAG : 0)) { // Really expensive thing // Update flags } } 这不是直观的if语句。我觉得应该有更好的方法,例如: if ((flags & AMAZING_FLAG) != doSet){ } 但这实际上不起作用,true似乎等于0x01。 因此,有没有一种比较布尔值的好方法?

1
为什么用time()报告的时间有时比C代码中的timespec_get()的秒部分晚1秒?
以下代码段: struct timespec ts; for (int x = 0; x < 100000000; x++) { timespec_get(&ts, TIME_UTC); long cTime = (long) time(NULL); if (cTime != ts.tv_sec && ts.tv_nsec < 3000000) { printf("cTime: %ld\n", cTime); printf("ts.tv_sec: %ld\n", ts.tv_sec); printf("ts.tv_nsec: %ld\n", ts.tv_nsec); } } 产生以下输出: ... cTime: 1579268059 ts.tv_sec: 1579268060 ts.tv_nsec: 2527419 cTime: …
12 c  time  posix  timespec 


1
为什么要为具有相同名称的函数定义宏?
我在https://github.com/torvalds/linux/blob/master/arch/x86/include/asm/atomic.h中找到了以下代码 static __always_inline bool arch_atomic_sub_and_test(int i, atomic_t *v) { return GEN_BINARY_RMWcc(LOCK_PREFIX "subl", v->counter, e, "er", i); } #define arch_atomic_sub_and_test arch_atomic_sub_and_test 什么是#define真的?什么时候需要这样做?
12 c  linux-kernel 

3
“ volatile”对于多核系统的可移植C代码是否有任何保证?
看着经过一大堆 的 其他 问题 和 他们的 答案,我得到的印象是有什么在C“挥发性”关键字表示正好没有广泛的协议。 即使标准本身似乎也不够清晰,每个人都无法理解其含义。 除其他问题外: 根据您的硬件和编译器,它似乎提供了不同的保证。 它影响编译器优化,但不影响硬件优化,因此在执行自己的运行时优化的高级处理器上,甚至不清楚编译器是否可以阻止您要阻止的任何优化。(某些编译器确实会生成指令来阻止某些系统上的某些硬件优化,但这似乎并未以任何方式进行标准化。) 总结一下问题,似乎(经过大量阅读)“ volatile”保证了类似的结果:该值将不但从/向寄存器,而且至少向内核的L1缓存中读/写,其顺序与读/写出现在代码中。但这似乎没有用,因为在同一个线程中读/写寄存器已经足够,而与L1缓存协调并不能保证与其他线程的协调。我无法想象仅与L1缓存进行同步的重要性。 用途1 唯一广泛同意使用volatile的似乎是旧的或嵌入式系统,其中某些内存位置通过硬件映射到I / O功能,例如内存中的某个位(直接在硬件中)控制灯光。 ,或告诉您键盘按键是否按下的内存中的某个位(因为它是通过硬件直接连接到按键的)。 看来,“用1”不移植的代码,其目标包括多核系统发生。 USE 2 与“ use 1”没什么不同,它是可由中断处理程序(可以控制灯光或从键存储信息)随时读取或写入的内存。但是为此已经存在一个问题,即取决于系统,中断处理程序可能会在 具有自己的内存缓存的不同内核上运行,并且“ volatile”不能保证所有系统上的缓存一致性。 因此,“使用2”似乎超出了“易失性”所能提供的范围。 用途3 我看到的唯一其他无可争议的用途是防止通过不同变量指向指向编译器未意识到的相同内存的不同内存的访问优化。但这可能只是无可争议的,因为人们没有在谈论它-我只看到其中一个提及。而且我认为C标准已经认识到“不同”的指针(例如指向函数的不同args)可能指向同一项目或附近的项目,并且已经指定编译器必须生成即使在这种情况下也可以工作的代码。但是,我无法在最新的标准(500页!)中快速找到此主题。 那么“使用3”也许根本不存在? 因此,我的问题是: 在多核系统的可移植C代码中,“ volatile”是否完全可以保证? 编辑-更新 浏览最新标准后,答案似乎至少是非常有限的: 1.标准针对特定类型“ volatile sig_atomic_t”反复指定特殊处理。但是该标准还说,在多线程程序中使用信号功能会导致不确定的行为。因此,该用例似乎仅限于单线程程序与其信号处理程序之间的通信。 2.该标准还为setjmp / longjmp指定了“ volatile”的明确含义。(在其他问题和答案中给出了重要示例代码)。 因此,更精确的问题变成了: 除了(1)允许单线程程序从其信号处理程序接收信息之外,还是(2)允许setjmp,“ volatile”是否可以保证多核系统的可移植C代码中的任何内容?代码以查看在setjmp和longjmp之间修改的变量? 这仍然是一个是/否问题。 如果为“是”,那么最好显示一个无错误的可移植代码示例,如果省略了“ volatile”,则该示例会出现错误。如果为“ no”,那么我认为对于多核目标,在这两种非常特殊的情况下,编译器可以随意忽略“ volatile”。

4
是否有一个C代码片段,可以在不使用编译器内置函数的情况下有效地计算溢出安全加法?
这是一个C函数,将C添加int到另一个函数,如果发生溢出将失败: int safe_add(int *value, int delta) { if (*value >= 0) { if (delta > INT_MAX - *value) { return -1; } } else { if (delta < INT_MIN - *value) { return -1; } } *value += delta; return 0; } 不幸的是,GCC或Clang 无法对其进行优化: safe_add(int*, int): movl (%rdi), %eax testl …

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.