javascript

java

python

c#

android

node.js

reactjs

c++

php

html

jquery

css

git

.net

ios

ruby-on-rails

sql

c

string

ruby

c-将数字范围映射到另一个

数学从来不是我在学校的强项:(

int input_start = 0; // The lowest number of the range input.
int input_end = 254; // The lowest number of the range input.
int output_start = 500; // The lowest number of the range output.
int output_end = 5500; // The largest number of the range ouput.

int input = 127; // Input value.
int output = 0;

如何将输入值转换为该范围的对应输出值?

例如,输入值“ 0”将等于输出值“ 500”,输入值“ 254”将等于输出值“ 5500”。 如果输入值是50或101,我不知道如何计算输出值。

我敢肯定这很简单,我现在无法思考:)

编辑:我只需要整数,没有分数或任何东西。

trans by 2019-11-18T07:06:34Z

c-如果有多个条件,则执行顺序

在具有多个条件的if语句中,如果第一个条件的结果明确,第二个条件条件执行吗?

例:

if(i>0 && array[i]==0){
}

如果我交换条件语句,则可能会针对i的负值发生段错误,但是这种方式不会发生段错误。 我可以确定这始终有效,还是必须使用嵌套的if语句?

trans by 2019-11-18T01:38:51Z

我可以在Windows上编译Unix的pthread.h吗?

如果我尝试使用编译程序

#include <pthread.h>

在其中,我得到了错误:

pthread.h: No such file or directory

是否可以在Windows环境中进行编译?

我正在将Vista与最新的MinGW配合使用。

我不想使用Microsoft Windows Services for UNIX 3.5版,因为我必须将其移至Unix环境。

trans by 2019-11-18T00:11:36Z

c-如何检测GDB是否正在运行当前进程?

标准方法如下:

if (ptrace(PTRACE_TRACEME, 0, NULL, 0) == -1)
  printf("traced!\n");

在这种情况下,如果跟踪了当前进程(即使用gdb运行或附加到gdb),则ptrace返回错误。

但这有一个严重的问题:如果调用成功返回,则gdb稍后可能不会附加到它。 这是一个问题,因为我没有尝试实现反调试的东西。 我的目的是在满足条件(即断言失败)并且gdb正在运行时发出“ int 3”(否则我得到一个SIGTRAP来停止应用程序)。

禁用SIGTRAP并每次发出'int 3'并不是一个很好的解决方案,因为我正在测试的应用程序可能出于其他其他目的使用SIGTRAP(在这种情况下,我还是被搞砸了,所以没关系,但这是 事情的原理:))

谢谢

trans by 2019-11-17T23:08:19Z

Makefile可以编译多个C程序?

这是一个非常简单的问题,但是我是makefile的新手。 我正在尝试制作一个可以编译两个独立程序的makefile:

program1:
    gcc -o prog1 program1.c

program2:
    gcc -o prog2 program2.c

在线上的所有示例都提供了比我所需更多的详细信息,令人困惑! 我真正想要做的就是运行两条gcc行。 我究竟做错了什么?

trans by 2019-11-17T19:54:07Z

Linux共享内存:shmget()vs mmap()?

在此线程中,建议OP使用shmget()而不是mmap()在Linux中获取共享内存。我访问了此页面,并获得了一些文档,但是第二个页面给出了一个关于mmap()的模糊示例。

几乎是新手,并且需要在两个进程之间共享一些信息(以文本形式),我应该使用shmget()方法还是mmap()? 又为什么呢

trans by 2019-11-17T19:47:33Z

保险丝-在C函数的开头,(无效)“变量名”是做什么的?

这个问题在这里已有答案:

  • 为什么将未使用的函数参数值强制转换为void?                                     2个答案

我正在从FUSE读取以下示例代码:

[http://fuse.sourceforge.net/helloworld.html]

而且我无法理解以下代码片段的作用:

static int hello_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
                         off_t offset, struct fuse_file_info *fi)
{
    (void) offset;
    (void) fi;

具体而言,(无效)“变量名”。 我以前从未在C程序中见过这种构造,所以我什至不知道要在Google搜索框中放入什么内容。 我目前的最佳猜测是它是未使用函数参数的某种说明符? 如果有人知道这是什么并且可以帮助我,那就太好了。 谢谢!

trans by 2019-11-17T19:09:37Z

c-如何在流程fork()之间共享内存?

在fork child中,如果我们修改全局变量,则它不会在主程序中被更改。

有没有办法在子fork中更改全局变量?

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

int glob_var;

main (int ac, char **av)
{
  int pid;

  glob_var = 1;

  if ((pid = fork()) == 0) {
    /* child */
    glob_var = 5;
  }
  else {
    /* Error */
    perror ("fork");
    exit (1);
  }

  int status;
  while (wait(&status) != pid) {
  }
   printf("%d\n",glob_var); // this will display 1 and not 5.
}
trans by 2019-11-17T18:53:11Z

c-`while(1)`的替代方法,以简化分支

这个问题在这里已有答案:

  • 做{…} while(false)                                     24个答案
  • 如何避免“如果”连锁?                                     51个答案

有时,我使用break块来压平连续的break不成比例的情况。 它遵循这些原则。

而不是做:

// process 
if (success) {
  // process 
  if (success) {
    //process
    if (success) {
      // etc
    }
  }
}

我做:

while (1) {
  // process
  if (!success) break;
  // process
  if (!success) break;
  // process
  if (!success) break;
  // etc
  break;
}

我对break末尾的隐式跳转感到有些恼火。我能否摆脱更精简的构造(即末尾没有break)?

我可以用变量(或寄存器?)交易最后的break。 这并不完全精简或清晰。

int once = 1;
while (once--) {
  // process
  if (!success) break;
  // process
  if (!success) break;
  // process
  if (!success) break;
  // etc
}

for循环看起来会更好一些(C99):

for (int once = 1 ; once--; once) {
  // process
  if (!success) break;
  // process
  if (!success) break;
  // process
  if (!success) break;
  // etc
}

我考虑过使用开关盒。 尽管它可以工作,但看起来并没有好多少。

switch (1) { default:
  // process
  if (!success) break;
  // process
  if (!success) break;
  // process
  if (!success) break;
  // etc
}

在那种特殊情况下,标签的概念似乎是无与伦比的。

// process
if (!success) goto end;
// process
if (!success) goto end;
// process
if (!success) goto end;
// etc

end:

你们还知道/使用什么其他方法?

trans by 2019-11-17T16:53:03Z

在C / C ++中获得正模的最快方法

通常,在我的内部循环中,我需要以“环绕”方式为数组建立索引,这样,如果数组大小为100,并且我的代码要求输入元素-2,则应为其指定元素98。在许多高级语言中,例如 与Python一样,您可以使用index轻松地做到这一点,但是由于某种原因,C的整数算术(通常)会四舍五入而不是始终四舍五入,因此,当给定第一个负数时,其模运算符将返回负数。

通常,我知道index不会小于-array_size,在这种情况下,我只做my_array[(index + array_size) % array_size]。但是,有时无法保证,对于这些情况,我想知道实现始终为正的模的最快方法 功能。 有几种“智能”方式可以做到而无需分支,例如

inline int positive_modulo(int i, int n) {
    return (n + (i % n)) % n
}

要么

inline int positive_modulo(int i, int n) {
    return (i % n) + (n * (i < 0))
}

当然,我可以对它们进行概要分析,以找出哪个是系统上最快的,但我不禁担心自己可能错过了更好的系统,或者在另一台计算机上计算机运行的速度可能较慢。

那么,有没有一种标准的方法来执行此操作,或者我错过了一些巧妙的技巧,而这可能是最快的方法?

另外,我知道这可能是一厢情愿的想法,但是如果有一种方法可以自动矢量化,那就太了不起了。

trans by 2019-11-17T11:28:56Z

C ++-常量变量无法正常运行

如果我像这样在标题中定义常量变量...

extern const double PI = 3.1415926535;
extern const double PI_under_180 = 180.0f / PI;
extern const double PI_over_180 = PI/180.0f;

我收到以下错误

1>MyDirectX.obj : error LNK2005: "double const PI" (?PI@@3NB) already defined in main.obj
1>MyDirectX.obj : error LNK2005: "double const PI_under_180" (?PI_under_180@@3NB) already defined in main.obj
1>MyDirectX.obj : error LNK2005: "double const PI_over_180" (?PI_over_180@@3NB) already defined in main.obj
1>MyGame.obj : error LNK2005: "double const PI" (?PI@@3NB) already defined in main.obj
1>MyGame.obj : error LNK2005: "double const PI_under_180" (?PI_under_180@@3NB) already defined in main.obj
1>MyGame.obj : error LNK2005: "double const PI_over_180" (?PI_over_180@@3NB) already defined in main.obj

但是如果我从标头中删除这些常量,然后将其放入包含标头的文档中,如下所示...

const double PI = 3.1415926535;
const double PI_under_180 = 180.0f / PI;
const double PI_over_180 = PI/180.0f;

有用

有谁知道我可能做错了什么?

谢谢

trans by 2019-11-17T09:08:38Z

struct-为什么C在->和。之间有区别?

好的,这没有什么严重的后果,但这一直困扰着我while:ps.xs.x运算符之间是否有区别的原因?

当然,当前规则是ps.x作用于结构,s.x作用于结构指向结构的指针(或并集)。 但是,这是它在实践中的工作方式。假设f是包含元素x的结构,并且让ps是指向相同形式的结构的指针。

如果你写

s->x

编译器将以以下方式发出警告:

你的意思是s.x。 请重新输入并重新编译。

如果你写

ps.x

编译器将以以下方式发出警告:

您的意思是ps-> x。 请重新输入并重新编译。

因为编译器在编译时知道ps.xs.x的类型,所以它具有解释正确运算符所需的所有信息。 我怀疑这与其他警告(例如缺少分号)不同,因为对正确的修复方法没有歧义。

因此,这是向C1x标准委员会提出的假想提案(由于ISO处于保守状态,因此永远不会考虑):

给定表达式lhs.rhs,如果lhs是结构或联合类型,       那么该表达式将引用名为rhs的lhs元素。       如果lhs的类型为pointer-to-struct或-union,则应为       解释为(* lhs).rhs。

这肯定会节省我们所有的时间,并使人们更容易学习C [而且我已经教了足够的C来权威地说,学习者发现ps.x东西既令人困惑又令人讨厌。

甚至有先例,C在其中做了一些类似的事情。 例如,出于实现的原因,函数声明始终强制转换为指向函数的指针,因此ps.xs.x都将起作用,而不管f是被声明为函数还是函数指针。

所以,我的问题是:该提案出了什么问题? 您是否可以想到在ps.xs.x之间存在致命歧义的示例,或者为什么保持强制性区别在其他方面有用呢?

trans by 2019-11-17T08:19:11Z

C + +返回值优化和复制省略

某些人不知道可以在C中按值传递和返回结构。我的问题是有关编译器在C中返回结构时是否制作不必要的副本。GCC之类的C编译器是否使用Return Value Optimization(RVO)优化? 仅C ++概念? 我读到的有关RVO和复制省略的所有内容都与C ++有关。

让我们考虑一个例子。我目前正在用C实现double-double数据类型(或者更确切地说是float-float,因为我发现它易于进行单元测试)。 考虑下面的代码。

typedef struct {
    float hi;
    float lo;
} doublefloat;

doublefloat quick_two_sum(float a, float b) {
    float s = a + b;
    float e = b - (s - a);
    return (doublefloat){s, e};
}

编译器会为我返回的doublefloat值制作一个临时副本,还是可以删除该临时副本?

C中的命名返回值优化(NRVO)呢? 我还有另一个功能

doublefloat df64_add(doublefloat a, doublefloat b) {
    doublefloat s, t;
    s = two_sum(a.hi, b.hi);
    t = two_sum(a.lo, b.lo);
    s.lo += t.hi;
    s = quick_two_sum(s.hi, s.lo);
    s.lo += t.lo;
    s = quick_two_sum(s.hi, s.lo);
    return s;
}

在这种情况下,我将返回一个命名结构。 在这种情况下可以删除临时副本吗?

应该指出,这是C语言的一个普遍问题,我在这里使用的代码示例仅是示例(当我对此进行优化时,无论如何我都将使用具有内在函数的SIMD)。 我知道我可以查看程序集输出以查看编译器的功能,但是我仍然认为这是一个有趣的问题。

trans by 2019-11-17T06:32:51Z

我可以将未签名的char转换为char,反之亦然吗?

我想使用一个期望这样的数据的函数:

void process(char *data_in, int data_len);

因此,它实际上只是在处理一些字节。

但是当涉及到原始字节时,我更喜欢使用“ unsigned char”(以某种方式“感觉”到只处理0到255的正值的权利),所以我的问题是:

我可以始终安全地将unsigned char *传递给此函数吗?

换一种说法:

  • 是否可以保证我可以随意在char和unsigned char之间安全地转换(转换)而不会丢失任何信息?
  • 我可以随意在指向char和未签名char的指针之间安全地转换(转换),而不会丢失任何信息吗?

奖励:在C和C ++中答案是否相同?

trans by 2019-11-17T06:01:19Z

c#4.0-是否可以从C#.N调用C函数

我有一个C库,想从C#应用程序中调用此库中的函数。 我尝试通过将C lib文件添加为链接器输入,并将源文件添加为附加依赖项,在C lib上创建C ++ / CLI包装器。

有什么更好的方法可以实现这一点,因为不确定如何将C输出添加到c#应用程序中。

我的C代码-

__declspec(dllexport) unsigned long ConnectSession(unsigned long handle,
                            unsigned char * publicKey,
                            unsigned char   publicKeyLen);

我的CPP包装器-

long MyClass::ConnectSessionWrapper(unsigned long handle,
                                unsigned char * publicKey,
                                unsigned char   publicKeyLen)
    {
        return ConnectSession(handle, publicKey, publicKeyLen);
    }
trans by 2019-11-16T22:34:43Z

如何从double中获取绝对值-C语言

我想要一个负双精度的绝对值-我认为double函数像在Java中一样易于使用-但不是!

似乎double函数返回一个int,因为我的值为3.8951并且输出为3.000000

double d1 = abs(-3.8951);
printf("d1: ...%lf", d1);

我该如何解决这个问题? 那就是-我想要一个double的绝对值。

trans by 2019-11-16T22:20:36Z

LINUX C中stdout和STDOUT_FILENO之间的区别

我想知道Linux C中stdoutSTDOUT_FILENO之间的区别。

经过一些搜索工作,我得出以下结论。 您能帮我查看一下并纠正其中的任何错误吗? 谢谢

  • stdout属于C语言的标准I / O流; 类型为FILE *并在stdio.h中定义

  • STDOUT_FILENO中定义了具有int类型的stdout。它是LINUX系统的文件描述符。 在stdout中,其解释如下:

stdout

因此,我认为stdout属于系统级调用,并且在某种程度上类似于系统API。 STDOUT_FILENO可用于描述系统中的任何设备。

stdout位于较高的级别(用户级别?),实际上封装了STDOUT_FILENO的详细信息。stdout具有I / O缓冲区。

这就是我对它们的区别的了解。 谢谢任何评论或纠正。

trans by 2019-11-16T09:55:36Z

C是否支持重载?

我只想知道C是否支持超载?当我们使用诸如printf之类的系统函数时,它们的参数个数不同。帮帮我

trans by 2019-11-16T01:25:46Z

va_end到底是干什么的? 总是有必要打电话吗?

arg_ptr-重置va_end()的宏。

访问变量参数列表后,通常用va_end()重置arg_ptr指针。我知道如果要重新迭代该列表是必需的,但是如果不想重复使用,确实需要吗? 就像“总是在您的switch中有switch”这样的规则一样,这只是一种好习惯吗?

trans by 2019-11-15T23:29:16Z

c-用于memcpy的增强型REP MOVSB

我想使用增强的REP MOVSB(ERMSB)为自定义memcpy获得高带宽。

ERMSB是与Ivy Bridge微体系结构一起引入的。 如果您不知道什么是ERMSB,请参阅英特尔优化手册中的“增强型REP MOVSB和STOSB操作(ERMSB)”部分。

我知道直接执行此操作的唯一方法是内联汇编。 我从[https://groups.google.com/forum/#!topic/gnu.gcc.help/-Bmlm_EG_fE]获得了以下功能

static inline void *__movsb(void *d, const void *s, size_t n) {
  asm volatile ("rep movsb"
                : "=D" (d),
                  "=S" (s),
                  "=c" (n)
                : "0" (d),
                  "1" (s),
                  "2" (n)
                : "memory");
  return d;
}

但是,当我使用它时,带宽比memcpy小得多。使用i7-6700HQ(Skylake)系统,Ubuntu 16.10,DDR4 @ 2400 MHz双通道32 GB,GCC 6.2,MOVSB copy可获得15 GB / s的速度和memcpy可获得26 GB / s的速度。

为什么memcpy的带宽这么低? 我该怎么做才能改善它?

这是我用来测试的代码。

//gcc -O3 -march=native -fopenmp foo.c
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stddef.h>
#include <omp.h>
#include <x86intrin.h>

static inline void *__movsb(void *d, const void *s, size_t n) {
  asm volatile ("rep movsb"
                : "=D" (d),
                  "=S" (s),
                  "=c" (n)
                : "0" (d),
                  "1" (s),
                  "2" (n)
                : "memory");
  return d;
}

int main(void) {
  int n = 1<<30;

  //char *a = malloc(n), *b = malloc(n);

  char *a = _mm_malloc(n,4096), *b = _mm_malloc(n,4096);
  memset(a,2,n), memset(b,1,n);

  __movsb(b,a,n);
  printf("%d\n", memcmp(b,a,n));

  double dtime;

  dtime = -omp_get_wtime();
  for(int i=0; i<10; i++) __movsb(b,a,n);
  dtime += omp_get_wtime();
  printf("dtime %f, %.2f GB/s\n", dtime, 2.0*10*1E-9*n/dtime);

  dtime = -omp_get_wtime();
  for(int i=0; i<10; i++) memcpy(b,a,n);
  dtime += omp_get_wtime();
  printf("dtime %f, %.2f GB/s\n", dtime, 2.0*10*1E-9*n/dtime);  
}

我对memcpy感兴趣的原因是基于这些评论

注意,在Ivybridge和Haswell上,如果缓冲区较大以适合MLC,则可以使用rep movsb击败movntdqa。 movntdqa导致RFO进入LLC,rep movsb不会...   在Ivybridge和Haswell上流传输到内存时,rep movsb的速度明显比movntdqa快(但请注意,在Ivybridge之前,它很慢!)

此memcpy实施中缺少什么/欠佳?


这是我在tinymembench的同一系统上得到的结果。

 C copy backwards                                     :   7910.6 MB/s (1.4%)
 C copy backwards (32 byte blocks)                    :   7696.6 MB/s (0.9%)
 C copy backwards (64 byte blocks)                    :   7679.5 MB/s (0.7%)
 C copy                                               :   8811.0 MB/s (1.2%)
 C copy prefetched (32 bytes step)                    :   9328.4 MB/s (0.5%)
 C copy prefetched (64 bytes step)                    :   9355.1 MB/s (0.6%)
 C 2-pass copy                                        :   6474.3 MB/s (1.3%)
 C 2-pass copy prefetched (32 bytes step)             :   7072.9 MB/s (1.2%)
 C 2-pass copy prefetched (64 bytes step)             :   7065.2 MB/s (0.8%)
 C fill                                               :  14426.0 MB/s (1.5%)
 C fill (shuffle within 16 byte blocks)               :  14198.0 MB/s (1.1%)
 C fill (shuffle within 32 byte blocks)               :  14422.0 MB/s (1.7%)
 C fill (shuffle within 64 byte blocks)               :  14178.3 MB/s (1.0%)
 ---
 standard memcpy                                      :  12784.4 MB/s (1.9%)
 standard memset                                      :  30630.3 MB/s (1.1%)
 ---
 MOVSB copy                                           :   8712.0 MB/s (2.0%)
 MOVSD copy                                           :   8712.7 MB/s (1.9%)
 SSE2 copy                                            :   8952.2 MB/s (0.7%)
 SSE2 nontemporal copy                                :  12538.2 MB/s (0.8%)
 SSE2 copy prefetched (32 bytes step)                 :   9553.6 MB/s (0.8%)
 SSE2 copy prefetched (64 bytes step)                 :   9458.5 MB/s (0.5%)
 SSE2 nontemporal copy prefetched (32 bytes step)     :  13103.2 MB/s (0.7%)
 SSE2 nontemporal copy prefetched (64 bytes step)     :  13179.1 MB/s (0.9%)
 SSE2 2-pass copy                                     :   7250.6 MB/s (0.7%)
 SSE2 2-pass copy prefetched (32 bytes step)          :   7437.8 MB/s (0.6%)
 SSE2 2-pass copy prefetched (64 bytes step)          :   7498.2 MB/s (0.9%)
 SSE2 2-pass nontemporal copy                         :   3776.6 MB/s (1.4%)
 SSE2 fill                                            :  14701.3 MB/s (1.6%)
 SSE2 nontemporal fill                                :  34188.3 MB/s (0.8%)

请注意,在我的系统上memcpy也比MOVSB copy快。


在我的原始测试中,我没有禁用turbo。 我禁用了turbo并再次进行了测试,但似乎没有太大的区别。 但是,更改电源管理确实有很大的不同。

当我做

sudo cpufreq-set -r -g performance

我有时看到memcpy超过20 GB / s。

sudo cpufreq-set -r -g powersave

我所看到的最好的速度约为17 GB / s。 但是memcpy似乎对电源管理不敏感。


我检查了启用和不启用SpeedStep的频率(使用sudo cpufreq-set -r performance),cpufreq-setperformance的空闲频率,1核心负载和4核心负载。 我运行了英特尔的MKL密集矩阵乘法来创建负载,并使用OMP_SET_NUM_THREADS设置线程数。这是结果表(以GHz为单位)。

              SpeedStep     idle      1 core    4 core
powersave     OFF           0.8       2.6       2.6
performance   OFF           2.6       2.6       2.6
powersave     ON            0.8       3.5       3.1
performance   ON            3.5       3.5       3.1

这表明即使使用SpeedStep禁用sudo cpufreq-set -r performance,也要禁用CPU仍然将时钟频率降至cpufreq-set的空闲频率。只有在没有SpeedStep的performance中,CPU才会以恒定频率运行。

我使用了例如sudo cpufreq-set -r performance(因为cpufreq-set给出了奇怪的结果)来更改电源设置。 这会重新打开turbo,因此之后我必须禁用turbo。

trans by 2019-11-15T10:37:53Z

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 下一页 共71页