小编qiu*_*bit的帖子

为什么GCC在实现整数除法时使用乘以奇数的乘法?

我一直在阅读divmul组装操作,我决定通过在C中编写一个简单的程序来实现它们:

文件分割

#include <stdlib.h>
#include <stdio.h>

int main()
{
    size_t i = 9;
    size_t j = i / 5;
    printf("%zu\n",j);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

然后生成汇编语言代码:

gcc -S division.c -O0 -masm=intel
Run Code Online (Sandbox Code Playgroud)

但是看生成的division.s文件,它不包含任何div操作!相反,它通过位移和魔术数字来做某种黑魔法.这是一个计算代码片段i/5:

mov     rax, QWORD PTR [rbp-16]   ; Move i (=9) to RAX
movabs  rdx, -3689348814741910323 ; Move some magic number to RDX (?)
mul     rdx                       ; Multiply 9 by magic number
mov     rax, rdx                  ; Take only the upper 64 bits of the …
Run Code Online (Sandbox Code Playgroud)

c assembly gcc x86-64 integer-division

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

缺少整数变化 - 需要O(n)解决方案

问题来自于Codility编程训练,它听起来如下:我们有一个数组(A []​​),其中n(范围从1到100,000)元素,这些是我们的参数.数组的元素是从-2,147,483,648到2,147,483,647的整数,我们需要找到数组中不存在的最小正整数.当然,这可以在O(n*log n)中轻松完成,方法是将它们全部排序并遍历排序的数组,查找缺少的正数(最后一个操作在我的解决方案中具有O(n)最差的时间复杂度).但根据Codility的说法,这个整体问题可以在O(n)中完成,我看不出有任何办法可以做到这一点.有人可以提供一些技巧让我不被卡住吗?

PS这是一个链接,详细描述了我不允许复制的问题 - https://codility.com/c/intro/demo35UEXH-EAT

algorithm

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

用于动态改变具有最长子序列长度查询的n长度序列的数据结构

我需要n使用以下方法设计保持长度序列的数据结构:

  • increasing() - 返回最长的子序列的长度
  • change(i, x) - 将x添加到序列的第i个元素

直观地说,这听起来像某种间隔树可解决的东西.但我不知道该怎么想.

我想知道如何使用这个事实,我们完全不需要知道这个子序列是怎样的,我们只需要它的长度......

也许这是可以使用的东西,但我现在几乎陷入困境.

algorithm data-structures

19
推荐指数
1
解决办法
570
查看次数

CMake - 如何为目标可执行文件设置多个编译定义?

我正在尝试为我尝试在CMake中编译的可执行文件之一设置多个编译定义(以激活用于调试的宏).这是我试过的:

add_executable (trie_io_test trie_io_test.c trie.c word_list.c)
    set_target_properties(
            trie_io_test
            PROPERTIES
            COMPILE_DEFINITIONS UNIT_TESTING=1)
    set_target_properties(
            trie_io_test
            PROPERTIES
            COMPILE_DEFINITIONS IO_TEST=1)
Run Code Online (Sandbox Code Playgroud)

不幸的是,这只会导致定义IO_TEST.

我也尝试过以下方法:

add_executable (trie_io_test trie_io_test.c trie.c word_list.c)
    set_target_properties(
            trie_io_test
            PROPERTIES
            COMPILE_DEFINITIONS UNIT_TESTING=1 IO_TEST=1)
Run Code Online (Sandbox Code Playgroud)

但另一方面,这会导致CMake错误.

如何为我正在尝试构建的可执行文件设置这两个定义?

cmake

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

valgrind - 地址是一个大小为16的块之前的8个字节

我遇到了"消化"valgrind输出的问题.这是一个片段:

==15145== Invalid write of size 8
==15145==    at 0x40168E: split_node_at_letter (in /home/pgolinski/Dokumenty/Programowanie/git/dictionary/trii)
==15145==    by 0x4018E7: pass_word_further (in /home/pgolinski/Dokumenty/Programowanie/git/dictionary/trii)
==15145==    by 0x401A35: insert_word (in /home/pgolinski/Dokumenty/Programowanie/git/dictionary/trii)
==15145==    by 0x401BD5: main (in /home/pgolinski/Dokumenty/Programowanie/git/dictionary/trii)
==15145==  Address 0x52237d8 is 8 bytes before a block of size 16 alloc'd
==15145==    at 0x4C29BCF: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==15145==    by 0x401063: add_to_trie_word_list (in /home/pgolinski/Dokumenty/Programowanie/git/dictionary/trii)
==15145==    by 0x40173B: pass_word_further (in /home/pgolinski/Dokumenty/Programowanie/git/dictionary/trii)
==15145==    by 0x40183D: pass_word_further (in /home/pgolinski/Dokumenty/Programowanie/git/dictionary/trii)
==15145==    by 0x401906: pass_word_further (in /home/pgolinski/Dokumenty/Programowanie/git/dictionary/trii)
==15145==    by 0x401A35: insert_word (in /home/pgolinski/Dokumenty/Programowanie/git/dictionary/trii) …
Run Code Online (Sandbox Code Playgroud)

c valgrind

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

检查是否在可变参数模板参数包中传递了类型

我听说过,使用新的C++ 1z语法,很容易检查是否在可变参数模板参数包中传递了一个类型 - 显然你可以使用接近一行长的代码来做到这一点.这是真的?那些相关的功能是什么?(我尝试通过折叠表达式查看但我无法看到如何在该问题中使用它们...)

以下是我在C++ 11中解决问题的方法,以供参考:

#include <type_traits>


template<typename T, typename ...Ts>
struct contains;

template<typename T>
struct contains<T> {
    static constexpr bool value = false;
};

template<typename T1, typename T2, typename ...Ts>
struct contains<T1, T2, Ts...> {
    static constexpr bool value = std::is_same<T1, T2>::value ? true : contains<T1, Ts...>::value;
};
Run Code Online (Sandbox Code Playgroud)

c++ templates type-traits c++17

8
推荐指数
1
解决办法
3051
查看次数

OCaml - 声明n维数组

我想在ocaml中创建三维数组.这是我试图做的事情:

let dp = Array.make n (Array.make n (Array.make k (-1))
Run Code Online (Sandbox Code Playgroud)

但它不起作用 - 更改值dp [0] [0] [0]会更改所有值dp [i] [j] [0].那么如何使用不同的数组创建矩阵,而不是使用相同的副本?

ocaml

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

是[n]真的可以与*(a + n)互换 - 为什么sizeof会返回两个不同的答案?

我在理解C中的一件事时遇到了问题.我在"ANSI C"中读过像数组a[n]在哪里的语句a实际上相当于*(a+n).所以这里是我编写的一个小代码片段,用于检查:

#include <stdio.h>
int main(void)
{
    int a[10] = {0,1,2,3,4,5,6,7,8,9};
    int *p = a;
    printf("sizeof a: %d\n", sizeof(a));
    printf("sizeof p: %d\n", sizeof(p));
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

执行代码后,程序输出:

sizeof a: 40
sizeof p: 8
Run Code Online (Sandbox Code Playgroud)

我不明白 - 我刚刚做了什么?如何ap不同的对象?(根据sizeof函数的输出来判断)

c arrays pointers

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

如果我不清除stringstream会发生什么?

我在TopCoder中做了一个图形问题,不知怎的,我的程序仍然输出错误的答案,即使我认为一切都应该没问题.我花了几个小时的时间在我的逻辑中寻找错误,事实证明,问题在于其他地方.这是一段代码,我有一个问题:

int x, y;
stringstream ssx;
stringstream ssy;
for (int i = 0; i < connects.size(); i++){
    neighbours.push_back(vector<int> ());
    edges_cost.push_back(vector<int> ());
    ssx.str(connects[i]);
    ssy.str(costs[i]);
    while (ssx >> x && ssy >> y){
        neighbours[i].push_back(x);
        edges_cost[i].push_back(y);
    }
    // The problem lied here. Apparently without these 2 lines
    // the program outputs wrong answer. Why?
    ssx.clear();
    ssy.clear();
}
Run Code Online (Sandbox Code Playgroud)

正如您在评论中看到的那样,我设法解决了这个问题.但我不知道为什么我需要清除那些串流.如果我不这样做,到底发生了什么?

c++ stringstream

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

C - 表示结构的位的操作

我正在尝试在C中编写hashset,并且我发现了一个哈希函数,它根据数据中的位进行哈希处理.我有以下结构:

struct triple
{
    int a;
    int b;
    int c;
};
Run Code Online (Sandbox Code Playgroud)

问题是 - 如何从类型的对象获取位表示struct triple?假设我想用8位整数对其位进行异或.我该怎么办?

c hash bit-manipulation

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