小编mar*_*nev的帖子

C固定大小的数组被视为可变大小

我一直在尝试定义一个大小应该在编译时知道的静态数组(它是一个常量表达式).看来gcc在包含浮点常量时无法确定数组的大小(我得到"存储大小为......不是常数").

这是一个最小的例子:

int main(void)
{
    static int foo[(unsigned)(2 / 0.5)];
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这种行为的原因是什么?

编辑

我已经有了我需要的答案.我仍然不明白不允许这种表达背后的理由,但这是一个单独的问题.我会解释好奇我是如何解决这个问题的.

这是一个我正在写作练习的游戏.单位在战场上移动,我已逐步划分了运动.我必须记住每个步骤中每个单元的位置,以便我以后可以显示动画.选择步数,以确保有一个步骤,使得单位足够接近以相互对抗但不会碰到碰撞.以下是相关的代码:

#define UNIT_SPEED_LIMIT 12
#define DISTANCE_MELEE 0.25
#define MOVEMENT_STEPS (unsigned)(2 * UNIT_SPEED_LIMIT / DISTANCE_MELEE)

struct position (*movements)[MOVEMENT_STEPS + 1];
Run Code Online (Sandbox Code Playgroud)

定义DISTANCE_MELEE(可以进行近战的最大距离)并使用它来计算步数似乎是继续进行的自然方式(更多是因为我在多个上下文中使用此常量).由于我无法定义movements这种方式,我必须发明一个概念,如"单个距离单位的步数",并使用乘法int而不是除以double.我想避免动态内存分配,以保持代码简单.

c c99

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

macro:来自char literal的字符串文字

在C中是否有办法使用宏从字符文字创建字符串文字?

比如我有

'a'
Run Code Online (Sandbox Code Playgroud)

我想创建字符串文字

"a"
Run Code Online (Sandbox Code Playgroud)

澄清问题:

#define A 'a'

write(fd, "x=" CHAR2STRING(A) "\n", 4);
Run Code Online (Sandbox Code Playgroud)

我的问题是如何定义宏CHAR2STRING

c c-preprocessor

7
推荐指数
1
解决办法
1416
查看次数

扩展类似函数的宏会创建一个单独的标记

我刚刚发现gcc似乎将类似函数的宏的扩展结果视为一个单独的标记.这是一个显示gcc行为的简单示例:

#define f() foo
void f()_bar(void);
void f()bar(void);
void f()-bar(void);
Run Code Online (Sandbox Code Playgroud)

当我执行gcc -E -P test.c(只运行预处理器)时,我得到以下输出:

void foo _bar(void);
void foo bar(void);
void foo-bar(void);
Run Code Online (Sandbox Code Playgroud)

看起来,在前两个定义中,gcc在扩展宏之后插入空格以确保它是一个单独的标记.这真的发生在这里吗?

这是否由任何标准强制执行(我找不到关于该主题的文档)?

我想做_bar同样的一部分.有没有办法做到这一点?我可以使用令牌连接运算符,##但它需要几个级别的宏(因为在实际代码中f()更复杂).我想知道是否有一个简单的(可能更具可读性)解决方案.

c macros c99

7
推荐指数
1
解决办法
133
查看次数

找到重叠的圆圈

我有一个矩形区域,其中有半径相等的圆。我想找到哪些圆与其他圆重叠(输出是重叠圆的 2 元素集的列表)。

我知道如何检查两个圆是否重叠(它们的中心之间的距离小于直径)。我可以对每对圆圈执行此检查,但我想知道是否有更好的算法(比 更快O(n^2))。

编辑

圆圈的数量通常在100个左右,并且不会经常发生重叠。

以下是一些背景信息:矩形是游戏中的战场。单位的移动是小步完成的,我正在尝试检测单位之间的碰撞。

algorithm computational-geometry data-structures

6
推荐指数
1
解决办法
2369
查看次数

NDK 错误“意外的本机构建目标 xyz。有效目标是:”

我有一个 Android Studio 项目,它依赖于本机共享库。我创建了一个 cmake 文件来编译该库,并在 android 项目中添加了一个指向共享库的软链接(在src/main/jniLibs/armeabi)。这样,当构建 android 项目时,共享库就会包含在包中。

这是相关部分build.gradle

android {
    ...
    externalNativeBuild {
        cmake {
            path "../cpp/CMakeLists.txt"
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

问题是 gradle 在调用构建共享库的指令之前尝试打开共享库。

Information:Gradle tasks [:app:assembleDebug]
Error:Could not list contents of 'app/src/main/jniLibs/armeabi/libfoo.so'. Couldn't follow symbolic link.
Run Code Online (Sandbox Code Playgroud)

如何从项目内部调用 cmake 并同时将库包含在项目中?

--

编辑

在 cmake 中,共享库是使用ExternalProject_Add. 不幸的是,gradle 没有看到该目标,也没有将导入的共享库视为目标。所以这不起作用:

add_library(libfoo SHARED IMPORTED GLOBAL)
add_dependencies(libfoo libactual)
Run Code Online (Sandbox Code Playgroud)

我尝试使用 gradle 配置调用构建特定目标:

defaultConfig {
    ...
    externalNativeBuild {
        cmake {
            targets "libfoo"
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

但 gradle 仍然没有看到它并失败:

Unexpected …
Run Code Online (Sandbox Code Playgroud)

shared-libraries gradle android-ndk

6
推荐指数
1
解决办法
2904
查看次数

C字符串数组

我想创建一个字符串数组.问题是我希望能够静态访问每个字符串的长度.我试过这个:

char *a[] = {"foo", "foobar"};
Run Code Online (Sandbox Code Playgroud)

数组工作正常,但我想静态地知道每个元素的长度.我无法使用,sizeof(a[0])因为它返回char *指针的大小.我想要的是字符串大小的长度(对于[0]为4,对于[1]为7).

有没有办法做到这一点?

c arrays string

5
推荐指数
1
解决办法
3294
查看次数

Javascript:数字的字符串表示

javascript 如何将数字转换为字符串?我希望它可以将数字四舍五入到一定的精度,但看起来情况并非如此。我做了以下测试:

> 0.1 + 0.2
0.30000000000000004
> (0.1 + 0.2).toFixed(20)
'0.30000000000000004441'
> 0.2
0.2
> (0.2).toFixed(20)
'0.20000000000000001110'
Run Code Online (Sandbox Code Playgroud)

这是 Safari 6.1.1、Firefox 25.0.1 和 node.js 0.10.21 中的行为。

看起来 javascript 显示 (0.1 + 0.2) 小数点后的第 17 位数字,但将其隐藏为 0.2(因此数字四舍五入为 0.2)。

数字到字符串的转换在 javascript 中究竟是如何工作的?

javascript string-formatting floating-point-precision

5
推荐指数
1
解决办法
1128
查看次数

数组的外部声明

我有一个数组,其大小在源文件中定义的编译时确定。

const int array[] = {1, 3, 3, 7};
Run Code Online (Sandbox Code Playgroud)

元素的数量将来可能会发生变化,因此我宁愿不在括号中对其进行硬编码。

这个数组需要从几个源文件中访问,所以我试图在头文件中添加一个 extern 声明。但是,由于隐式数组大小,我不确定这是否可行。我尝试了两种变体:

extern const int array[]; // Warning: size of symbol `array' changed from 8 to 16
extern const int *array; // error: conflicting types for 'array'
Run Code Online (Sandbox Code Playgroud)

是否可以这样做,或者我应该寻找解决方法?

c99 extern variable-declaration

3
推荐指数
1
解决办法
3022
查看次数

void * 和 char * 之间的兼容性

void 和 char 指针是否保证具有相同的内存表示形式?

换句话说,执行以下命令后:

char a = 'z';
void *b = &a;
char *c;

memcpy(&c, &b, sizeof(b));
Run Code Online (Sandbox Code Playgroud)

我可以确定*c == 'z'(没有未定义的行为等)吗?

c c99 void-pointers language-lawyer

3
推荐指数
1
解决办法
133
查看次数

C 中的操作重排序和符号性

我发现了几个讨论有符号与无符号编译器优化的问题。一般结论是,由于溢出的未定义行为,有符号允许更多优化。但是,我没有找到任何关于签名如何与操作重新排序一起发挥作用的讨论。

考虑表达式

a - b + c
Run Code Online (Sandbox Code Playgroud)

如果所有值都是无符号的,编译器总是可以重新排序操作(添加ac首先可以提高性能)。

如果所有值都有符号,编译器必须证明重新排序不会导致发生溢出。一般来说a + c,编译器可能会溢出,因此它可以重新排序的内容受到限制。

我是否正确地认为编译器可以更自由地对无符号值的操作进行重新排序?


编辑

我本来想问有关*and等其他操作,但我想这个问题只对and/有意义。一般来说,无论整数是有符号还是无符号,乘法和除法都不能重新排序。+-

c signed c99 compiler-optimization

2
推荐指数
1
解决办法
81
查看次数

GCC寄存器优化

嗨,我对gcc从这段代码生成的汇编代码感兴趣(这只是用于说明我的观点的虚拟代码):

int a = 0;
int foo(void)
{
    int result = a;
    a += 2;
    return result;
}
Run Code Online (Sandbox Code Playgroud)

我很惊讶gcc将变量a复制到堆栈,然后从堆栈复制到寄存器,以便它可以返回它.当我将register添加到结果声明时,它优化了代码不使用堆栈,而是将变量直接复制到寄存器.我知道这并没有什么区别,但我想知道为什么gcc没有隐含地进行这样的优化.我希望我说清楚我在谈论什么......

有任何想法吗?

c assembly gcc

0
推荐指数
1
解决办法
948
查看次数