小编chq*_*lie的帖子

在C中实现atoi

我无法理解以下atoi实现代码,特别是这一行: atof

代码:

k = (k << 3) + (k << 1) + (*p) - '0';
Run Code Online (Sandbox Code Playgroud)

有人可以向我解释一下吗?

另一个问题:atoi实施算法应该是什么?

c atoi atof

25
推荐指数
2
解决办法
3万
查看次数

当sizeof(int)== 4时,1 << 31在C中定义得很好

根据这个问题的答案:

E1 << E2的结果是E1左移E2位位置; 腾出的位用零填充.如果E1具有无符号类型,则结果的值为E1×2 E2,比结果类型中可表示的最大值减少一个模数.如果E1具有带符号类型和非负值,并且E1×2 E2可在结果类型中表示,那么这就是结果值; 否则,行为未定.

这似乎意味着1 << 31未定义.

但是,如果我使用,GCC不会发出警告1 << 31.它确实发出一个问题1 << 32. 链接

那是哪个呢?我误解了标准吗?海湾合作委员会有自己的解释吗?

c bit-shift undefined-behavior language-lawyer

25
推荐指数
3
解决办法
1924
查看次数

是否需要C enum中的最后一个逗号?

C enum声明中是否需要最后一个逗号?

即是VAL3必要后的逗号?

enum { Val1, Val2, Val3, } someEnum;
Run Code Online (Sandbox Code Playgroud)

将其留入/取出是否有任何副作用

谢谢

c syntax enums

22
推荐指数
4
解决办法
1万
查看次数

Big-O小澄清

O(log(log(n)))实际上只是O(log(n))当谈到时间复杂度?
你是否同意这个函数g()的时间复杂度O(log(log(n)))

int f(int n) {
    if (n <= 1)
        return 0;
    return f(n/2) + 1;
}

int g(int n) {
    int m = f(f(n));
    int i;
    int x = 0;
    for (i = 0; i < m; i++) {
        x += i * i;
    }
    return m;
}
Run Code Online (Sandbox Code Playgroud)

c big-o time-complexity

20
推荐指数
2
解决办法
1497
查看次数

使用匿名结构与使用typedef的命名结构

何时应该使用以下陈述之一?

typedef struct Foo {
    int a;
} Bar;
Run Code Online (Sandbox Code Playgroud)

typedef struct {
    int a;
} Bar;
Run Code Online (Sandbox Code Playgroud)

并使用它

Bar bar1 = { 5 };
Run Code Online (Sandbox Code Playgroud)

我理解第二个是匿名结构但不确定何时应该使用另一个结构.

c

20
推荐指数
4
解决办法
1232
查看次数

由于标准C委员会没有标准化gets()的简单替换,它应该是什么?

gets函数首先在C99中弃用,最后在C11中删除.然而,在C库中没有直接替代它.

fgets()不是替代品,因为它不会剥离最终版本'\n',这可能在文件末尾不存在.许多程序员也错了.

有一个单行代码可以删除换行符:buf[strcspn(buf, "\n")] = '\0';但它不重要,通常需要解释.它也可能效率低下.

这会适得其反.许多初学者仍然使用,gets()因为他们的老师是蹩脚的或他们的教程已经过时.

微软提出了gets_s()许多相关的函数,但它并没有默默地截断超长行,这种约束违规的行为并不简单.

BSD和GNU libc都getline在POSIX中标准化,通过realloc... 分配或重新分配缓冲区.

教初学者关于这个混乱的最佳方法是什么?

c glibc libc language-lawyer

19
推荐指数
2
解决办法
329
查看次数

是否有理由避免使用位域结构成员?

我早就知道C中有位字段,偶尔我会用它们来定义密集的结构:

typedef struct Message_s {
     unsigned int flag : 1;
     unsigned int channel : 4;
     unsigned int signal : 11;
} Message;
Run Code Online (Sandbox Code Playgroud)

当我阅读开源代码时,我经常会发现位掩码和位移操作,以便在手工滚动的位域中存储和检索这些信息.这是如此常见,我不认为作者不知道位字段语法,所以我想知道是否有理由通过位掩码滚动位字段并转移自己的操作而不是依赖编译器生成用于获取和设置此类位字段的代码.

c struct principles c99 bit-fields

19
推荐指数
2
解决办法
1987
查看次数

多维数组访问是否按顺序进行?

采取以下措施:

int a(void) {
    puts("a");
    return 0;
}

int b(void) {
    puts("b");
    return 1;
}

int c(void) {
    puts("c");
    return 2;
}

int d(void) {
    puts("d");
    return 3;
}
Run Code Online (Sandbox Code Playgroud)

以下行为会有可预测的行为吗?

int arr[4][4][4][4];
arr[a()][b()][c()][d()] = 1;
Run Code Online (Sandbox Code Playgroud)

是否保证按这个顺序打印:

int a(void) {
    puts("a");
    return 0;
}

int b(void) {
    puts("b");
    return 1;
}

int c(void) {
    puts("c");
    return 2;
}

int d(void) {
    puts("d");
    return 3;
}
Run Code Online (Sandbox Code Playgroud)

我知道以下结构是无效的:

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

这是因为=是一个无序运算符,因此是否首先计算ii++是未定义的。在另一个序列点之前访问和修改单个对象是未定义的行为。

换句话说,以下内容是否有效:

int i …
Run Code Online (Sandbox Code Playgroud)

c arrays multidimensional-array undefined-behavior order-of-execution

18
推荐指数
2
解决办法
2432
查看次数

C23 中 int main() 和 int main(void) 等价原型吗?

C23 在函数声明符中引入了新的语义:

\n
\n

6.7.6.3 函数声明符

\n

[...]

\n

13\xc2\xa0\xc2\xa0\xc2\xa0对于没有参数类型列表的函数声明符:效果就像是使用由关键字 组成的参数类型列表进行声明void。函数声明符提供函数的原型。

\n
\n

这似乎意味着具有空参数列表的函数定义可以等效地用()or编写(void)

\n

然而,该函数似乎并不能保证这种main等价性:

\n
\n

5.1.2.2.1 程序启动

\n

程序启动时调用的函数名为main。该实现没有声明该函数的原型。它的返回类型应为int且不带参数定义:

\n
int main(void) { /* ... */ }\n
Run Code Online (Sandbox Code Playgroud)\n

或带有两个参数(此处称为argcargv,但可以使用任何名称,因为它们对于声明它们的函数来说是本地的):

\n
int main(int argc, char *argv[]) { /* ... */ }\n
Run Code Online (Sandbox Code Playgroud)\n

或等效的或以某种其他实现定义的方式。

\n
\n

这似乎并不能保证 是 的int main() { /* ... */ }有效定义main,或者等效定义是否涵盖此变体?

\n
\n …

c language-lawyer function-prototypes c23

18
推荐指数
1
解决办法
2789
查看次数

连续数组

我很好奇C18标准中的一句话:

两个指针比较相等当且仅当它们都是空指针,都是指向同一个对象的指针(包括指向一个对象的指针和它开头的子对象)或函数,都是指向同一数组最后一个元素之后的指针对象,或者一个是指向一个数组对象末尾的指针,另一个是指向另一个数组对象开头的指针,该对象恰好紧跟地址空间中的第一个数组对象。§ 6.5.9 6

为什么数组后面的对象必须是另一个数组?不能简单地成为与数组基类型相同类型的对象(例如int紧跟在 之后的int[])?

难怪我试过这个代码:

#include <stdio.h>

struct test { int arr[10]; int i; };

int main() {
    struct test t;
    int *p, *q;
    p = t.arr + 10;
    q = &t.i;
    if (p == q)
        printf("Equal pointers.");
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

它产生相等的指针。这种行为是否根本没有保证,只是实现定义的巧合?

c arrays

16
推荐指数
2
解决办法
818
查看次数