我需要一个函数,它接受任意数量的参数(所有相同的类型),对它们做一些事情然后给出一个结果.在我的具体情况下,参数列表是不切实际的.
当我查看haskell库时,我看到函数printf(来自模块Text.Printf)使用了类似的技巧.不幸的是,通过查看来源我无法理解这种魔力.
有人可以解释如何实现这一点,或至少一些网页/纸/任何我可以找到一个良好的描述吗?
动机:
我需要它的原因非常简单.对于学校(计算机科学课),我们需要编写一个能够"记录"数学表达式,将其表示为字符串的模块(通过为自己的数据类型编写Num/Real/etc的实例),并执行对它的各种操作.
此数据类型包含变量的特殊构造函数,可以由值或指定函数的任何值替换.其中一个目标是编写一个函数,它使用一些变量(类型对(Char,Rational))来表达这种表达式并计算表达式的结果.我们应该看看如何最好地表达函数的目标.(我的想法:该函数返回另一个函数,它接受与函数中定义的变量一样多的参数 - 似乎是不可能的).
我试着学习箭的含义,但我不理解它们.
我使用了Wikibooks教程.我认为Wikibook的问题主要在于它似乎是为那些已经理解了这个主题的人写的.
有人可以解释箭头是什么以及我如何使用它们?
Haskell通常被引用为纯函数式语言的示例.鉴于存在,这怎么可能是合理的System.IO.Unsafe.unsafePerformIO?
编辑:我认为"纯功能"意味着不可能将不纯的代码引入程序的功能部分.
haskell type-systems functional-programming referential-transparency unsafe-perform-io
当你学习C++时,或者至少当我通过C++ Primer学习它时,指针被称为它们指向的元素的"内存地址".我想知道这是多少.
例如,做两个元素*p1并*p2拥有属性,p2 = p1 + 1或者p1 = p2 + 1 当且仅当它们在物理内存中相邻时?
考虑使用C程序(请参阅此处的实时演示).
const int main = 195;
Run Code Online (Sandbox Code Playgroud)
我知道在现实世界中没有程序员编写这样的代码,因为它没有任何用处,也没有任何意义.但是当我const从程序上方删除关键字时,它会立即导致分段错误.为什么?我很想知道这背后的原因.
GCC 4.8.2在编译时会发出以下警告.
警告:'main'通常是一个函数[-Wmain]
Run Code Online (Sandbox Code Playgroud)const int main = 195; ^
为什么const关键字的存在和缺失会对程序的行为产生影响?
我克隆了GHC(格拉斯哥Haskell编译器)存储库.为了构建编译器,您需要几个库,它们都可以作为git存储库使用.为了方便现场使用,GHC黑客包括一个脚本sync-all,在执行时会更新所有相关的存储库.
现在我的问题是:./sync-all pull我git pull自动完成后如何让git执行?我听说过使用挂钩,但我真的不知道,我该怎么办.
正如先前建立的,形式的联合
union some_union {
type_a member_a;
type_b member_b;
...
};
Run Code Online (Sandbox Code Playgroud)
与Ñ成员包括Ñ在重叠存储+ 1对象:联合本身一个目的并且对于每个联盟成员一个对象.很明显,您可以按任何顺序自由地读取和写入任何工会成员,即使读取的工会成员不是最后写入的工会成员.永远不会违反严格别名规则,因为访问存储的左值具有正确的有效类型.
脚注95 进一步支持了这一点,脚注95解释了类型双关语是否是联盟的预期用途.
严格别名规则启用的优化的典型示例是此函数:
int strict_aliasing_example(int *i, float *f)
{
*i = 1;
*f = 1.0;
return (*i);
}
Run Code Online (Sandbox Code Playgroud)
编译器可能会优化到类似的东西
int strict_aliasing_example(int *i, float *f)
{
*i = 1;
*f = 1.0;
return (1);
}
Run Code Online (Sandbox Code Playgroud)
因为它可以安全地假设写入*f不会影响值*i.
但是,当我们将两个指针传递给同一个联盟的成员时会发生什么?考虑这个例子,假设一个典型的平台float是IEEE 754单精度浮点数,并且int是32位二进制补码整数:
int breaking_example(void)
{
union {
int i;
float f;
} fi;
return (strict_aliasing_example(&fi.i, &fi.f));
} …Run Code Online (Sandbox Code Playgroud) 我要说的是,goto在C/C++编程方面,使用被认为是一种不好的做法.
但是,给出以下代码
for (i = 0; i < N; ++i)
{
for (j = 0; j < N; j++)
{
for (k = 0; k < N; ++k)
{
...
if (condition)
goto out;
...
}
}
}
out:
...
Run Code Online (Sandbox Code Playgroud)
我想知道如何有效地实现相同的行为而不使用goto.我的意思是我们可以做一些事情,例如condition在每个循环结束时检查,但是AFAIK goto将只生成一个汇编指令jmp.所以这是我能想到的最有效的方法.
有没有其他被认为是好的做法?当我说使用goto被认为是一种不好的做法时,我错了吗?如果我,这是否是使用它的好情况之一?
谢谢
获取一个对齐的内存块有几个选项,但它们非常相似,问题主要归结为您所针对的语言标准和平台.
C11
void * aligned_alloc (size_t alignment, size_t size)
Run Code Online (Sandbox Code Playgroud)
POSIX
int posix_memalign (void **memptr, size_t alignment, size_t size)
Run Code Online (Sandbox Code Playgroud)
视窗
void * _aligned_malloc(size_t size, size_t alignment);
Run Code Online (Sandbox Code Playgroud)
当然,手动对齐也是一种选择.
英特尔提供另一种选择
英特尔
void* _mm_malloc (int size, int align)
void _mm_free (void *p)
Run Code Online (Sandbox Code Playgroud)
基于英特尔发布的源代码,这似乎是分配工程师喜欢的对齐内存的方法,但我找不到任何将其与其他方法进行比较的文档.我发现的最接近的只是承认存在其他对齐的内存分配例程.
要动态分配一段对齐的内存,请使用posix_memalign,它由GCC和Intel Compiler支持.使用它的好处是您不必更改内存处理API.您可以像往常一样使用free().但要注意参数配置文件:
int posix_memalign(void**memptr,size_t align,size_t size);
英特尔编译器还提供另一组内存分配API.C/C++程序员可以使用_mm_malloc和_mm_free来分配和释放对齐的内存块.例如,以下语句为8个浮点元素请求64字节对齐的内存块.
farray =(float*)__ mm_malloc(8*sizeof(float),64);
必须使用_mm_free释放使用_mm_malloc分配的内存.在使用_mm_malloc分配的内存上调用free或在使用malloc分配的内存上调用_mm_free将导致不可预测的行为.
从用户的角度来看,明显的区别是_mm_malloc需要直接的CPU和编译器支持以及分配的内存_mm_malloc必须被释放_mm_free.鉴于这些缺点,使用_mm_malloc?它的原因是什么?它有轻微的性能优势吗?历史事故?