标签: c

为什么volatile在多线程C或C++编程中不被认为有用?

正如我最近发布的这个答案所示,我似乎对volatile多线程编程环境中的实用程序(或缺乏实用程序)感到困惑.

我的理解是这样的:每当一个变量可以在访问它的一段代码的控制流之外被改变时,该变量应该被声明为volatile.信号处理程序,I/O寄存器和由另一个线程修改的变量都构成这种情况.

所以,如果你有一个全局int foo,并且foo由一个线程读取并由另一个线程原子设置(可能使用适当的机器指令),则读取线程看到这种情况的方式与它看到由信号处理程序调整的变量或由外部硬件条件修改,因此foo应该声明volatile(或者,对于多线程情况,使用内存隔离负载访问,这可能是一个更好的解决方案).

我怎么错,哪里错了?

c c++ multithreading volatile c++-faq

159
推荐指数
8
解决办法
6万
查看次数

什么是最快的子串搜索算法?

好吧,所以我听起来不像白痴我会更明确地陈述问题/要求:

  • 针(模式)和haystack(要搜索的文本)都是C样式的以空字符结尾的字符串.没有提供长度信息; 如果需要,必须计算.
  • 函数应该返回指向第一个匹配的指针,或者NULL如果找不到匹配项.
  • 不允许发生失败案件.这意味着任何具有非常量(或大常量)存储要求的算法都需要具有分配失败的后备情况(并且后备保养中的性能因此导致最坏情况的性能).
  • 实现是在C中,虽然没有代码的算法(或链接到这样的)的良好描述也很好.

......以及"最快"的意思:

  • 确定性O(n)where n= haystack长度.(但是O(nm)如果它们与更强大的算法组合以给出确定性O(n)结果,则可以使用通常(例如滚动哈希)算法的思想.
  • 从不执行(可测量;一些时钟if (!needle[1])等等)比天真蛮力算法更糟糕,特别是在非常短的针上,这可能是最常见的情况.(无条件的重预处理开销是不好的,因为试图以可能的针头为代价来改善病理针的线性系数.)
  • 给定任意针和干草堆,与任何其他广泛实现的算法相比,具有相当或更好的性能(不低于搜索时间长50%).
  • 除了这些条件,我将保留"最快"开放式的定义.一个好的答案应该解释为什么你认为你建议"最快"的方法.

我目前的实现比glibc实现的双向大约慢10%和8倍(取决于输入).

更新:我目前的最佳算法如下:

  • 对于长度为1的针,请使用strchr.
  • 对于长度为2-4的针,使用机器字一次比较2-4个字节,如下所示:在每次迭代时从大海捞针以16位或32位整数预加载针,并从大海捞针中循环旧字节输出/新字节.大海捞针的每个字节都只读取一次,并对0(字符串结束)和一个16位或32位比较进行检查.
  • 对于长度> 4的针,使用具有错误移位表的双向算法(如Boyer-Moore),该移位表仅应用于窗口的最后一个字节.为了避免初始化1kb表的开销,这对于许多中等长度的针来说是一个净损失,我保留一个位数组(32字节)标记移位表中的哪些条目被初始化.未设置的位对应于从不出现在针中的字节值,可以进行全针长度移位.

我脑海中留下的重大问题是:

  • 有没有办法更好地利用坏班次表?Boyer-Moore通过向后扫描(从右到左)充分利用它,但是双向扫描需要从左到右扫描.
  • 我在一般情况下找到的唯一两个可行的候选算法(没有内存或二次性能条件)是有序字母表上的双向字符串匹配.但是,是否存在易于检测的情况,其中不同的算法将是最佳的?当然,空间算法中的许多O(m)(其中m是针长)可以用于m<100左右.如果针对针的简单测试可能仅需要线性时间,那么也可以使用最坏情况二次方的算法.

奖励积分:

  • 假设针和干草堆都是结构良好的UTF-8,你能提高性能吗?(对于字节长度不同的字符,良好的形式在针和haystack之间强加了一些字符串对齐要求,并且当遇到不匹配的头字节时允许自动2-4字节移位.但这些约束是否会超出你的范围最大后缀计算,良好的后缀转换等已经为您提供了各种算法?)

注意:我很清楚那里的大多数算法,而不是它们在实践中的表现.这是一个很好的参考,所以人们不会继续给我作为评论/答案的算法参考:http://www-igm.univ-mlv.fr/~lecroq/string/index.html

c string algorithm substring

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

为什么在计算数组的中间时更喜欢start +(end-start)/ 2 over(start + end)/ 2?

我见过程序员使用这个公式

mid = start + (end - start) / 2
Run Code Online (Sandbox Code Playgroud)

而不是使用更简单的公式

mid = (start + end) / 2
Run Code Online (Sandbox Code Playgroud)

用于查找数组或列表中的中间元素.

他们为什么使用前者呢?

c algorithm

159
推荐指数
3
解决办法
9546
查看次数

是否有替代unistd.h for Windows(Visual C)?

我正在将一个为Unix编写的相对简单的控制台程序移植到Windows平台(Visual C++ 8.0).所有源文件都包含"unistd.h",它不存在.删除它,我得到关于'srandom','random'和'getopt'错误原型的投诉.我知道我可以替换随机函数,我很确定我可以找到/ hack-up一个getopt实现.

但我相信其他人也遇到了同样的挑战.我的问题是:Windows中有"unistd.h"端口吗?至少有一个包含那些具有本机Windows实现的功能 - 我不需要管道或分叉.

编辑:

我知道我可以创建我自己的"unistd.h",其中包含我需要的东西的替换 - 特别是在这种情况下,因为它是一个有限的集合.但是,由于它似乎是一个常见的问题,我想知道是否有人已经为更大的功能部分完成了工作.

无法在工作中切换到不同的编译器或环境 - 我坚持使用Visual Studio.

c c++ windows portability unistd.h

158
推荐指数
5
解决办法
27万
查看次数

警告:内置函数'xyz'的隐式声明不兼容

编译几个二进制文件时,我收到了一些警告:

warning: incompatible implicit declaration of built-in function ‘strcpy’
warning: incompatible implicit declaration of built-in function ‘strlen’
warning: incompatible implicit declaration of built-in function ‘exit’
Run Code Online (Sandbox Code Playgroud)

为了解决这个问题,我补充道

#include <stdlib.h>
Run Code Online (Sandbox Code Playgroud)

在与此警告关联的C文件的顶部,除了使用以下标志进行编译之外:

CFLAGS = -fno-builtin-exit -fno-builtin-strcat -fno-builtin-strncat -fno-builtin-strcpy -fno-builtin-strlen -fno-builtin-calloc
Run Code Online (Sandbox Code Playgroud)

我正在使用GCC 4.1.2:

$ gcc --version
gcc (GCC) 4.1.2 20080704
Run Code Online (Sandbox Code Playgroud)

我该怎么做才能解决这些警告?

c gcc gcc-warning

158
推荐指数
4
解决办法
35万
查看次数

为什么在C布尔宏中#define为TRUE(1 == 1)而不是简单为1?

我见过C中的定义

#define TRUE (1==1)
#define FALSE (!TRUE)
Run Code Online (Sandbox Code Playgroud)

这有必要吗?简单地将TRUE定义为1,将FALSE定义为0有什么好处?

c precompiler

158
推荐指数
5
解决办法
2万
查看次数

如何在C程序中获取当前目录?

我正在制作一个C程序,我需要从中获取程序启动的目录.该程序是为UNIX计算机编写的.我一直在寻找opendir()telldir(),但telldir()返回off_t (long int),所以它确实没有帮助我.

如何在字符串(char数组)中获取当前路径?

c unix working-directory

157
推荐指数
4
解决办法
25万
查看次数

C++中size_t和int之间有什么区别?

在几个C++示例中,我看到使用size_t类型,我将使用一个简单的int.有什么区别,为什么size_t应该更好?

c c++ int types

157
推荐指数
4
解决办法
12万
查看次数

为什么在没有返回值的情况下流出非void函数的末尾不会产生编译器错误?

自从我多年前意识到这一点,默认情况下这不会产生错误(至少在GCC中),我一直想知道为什么?

我知道您可以发出编译器标志来产生警告,但是它不应该总是出错吗?为什么非void函数没有返回值才有效?

评论中要求的示例:

#include <stdio.h>
int stringSize()
{
}

int main()
{
    char cstring[5];
    printf( "the last char is: %c\n", cstring[stringSize()-1] ); 
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

...编译.

c c++ gcc g++

157
推荐指数
5
解决办法
4万
查看次数

字符串文字:它们去哪儿了?

我对字符串文字的分配/存储感兴趣.

我确实在这里找到了一个有趣的答案,说:

定义内联字符串实际上是将数据嵌入程序本身并且无法更改(某些编译器通过智能技巧允许这样做,不要打扰).

但是,它与C++有关,更不用说它不打扰了.

我很烦.= d

所以我的问题是我的字符串文字保存在哪里以及如何保存?我为什么不试着改变呢?实施是否因平台而异?有没有人愿意详细说明"聪明的伎俩"?

c memory string-literals

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