我在C中有一个大数组(如果有所不同,则不是C++).我想将所有成员初始化为相同的值.我发誓我曾经知道一个简单的方法来做到这一点.我可以memset()
在我的情况下使用,但是没有办法在C语法中构建这样做吗?
这不是建议的做法(也不是未定义的行为),而是关于将整数类型的所有字节转换为值的c ++标准实际上保证的内容
(unsigned char)0
.
在下面的代码片段中,if-statement使用的表达式是否保证在c ++ 11中被评估为true?
std::memset (
reinterpret_cast<char*> (&a), // int a;
(unsigned char)0,
sizeof (int)
);
if (a == 0) {
...
}
Run Code Online (Sandbox Code Playgroud)
通过阅读C99和C++ 11标准中的引文(在本文中进一步说明),我们发现C99明确保证所有位设置为的整数类型0
将表示该0
类型中的值.
我在C++ 11标准中找不到这种保证.
5.2.1.2/1多字节字符
所有位为零的字节应被解释为与移位状态无关的空字符.这样的字节不应作为任何其他多字节字符的一部分出现.
6.2.6.2/1整数类型
任何填充位的值都是未指定的.45)符号位为零的有符号整数类型的有效(非陷阱)对象表示是相应无符号类型的有效对象表示,并且应表示相同的值.
对于任何整数类型,所有位为零的对象表示应该是该类型中零值的表示.
2.3/3字符集[lex.charset]
基本执行字符集和基本执行宽字符集应各自包含基本源字符集的所有成员,以及表示alert,backspace和回车符的控制字符,以及空字符(分别为null宽字符),其表示具有全零位.
我们毫无疑问地知道,ISO C标准(以及C++,我认为,虽然我对C方面更感兴趣)允许签名数字的三个基础表示:
维基百科的条目表明,60年代的IBM 7090使用了标志/幅度,PDP-1,CDC 160A和UNIVAC 1100使用的是补充,所有这些都可以追溯到60年代.
是否有其他任何具有这些替代表示的C(或底层硬件)实现,这些实现比五十年前更新了(它们是什么)?
对于不再存在的机器,保持某种标准似乎有点浪费.
char str[] = "beautiful earth";
memset(str, '*', 6);
printf("%s", str);
Output:
******ful earth
Run Code Online (Sandbox Code Playgroud)
1)像上面使用memset一样,我们可以只将几个整数数组索引值初始化为1,如下所示?
int arr[15];
memset(arr, 1, 6);
Run Code Online (Sandbox Code Playgroud) 如何初始化使用malloc分配的动态数组?我可以这样做:
int *p;
p = malloc(3 * sizeof(*p));
p = {0, 1, 2};
...
free(p);
Run Code Online (Sandbox Code Playgroud)
或者我需要做这样的事情:
int *p, x;
p = malloc(3 * sizeof(*p));
for (x = 0; x < 3; x++)
p[x] = 0;
...
free(p);
Run Code Online (Sandbox Code Playgroud)
或者有更好的方法吗?
calloc()
双场的总评估为0.0
?此外:
calloc()
一个的float
领域始终评估为0.0f
?calloc()
一个int
或unsigned int
领域始终评估为0
?也就是说,assert()
以下总是能在所有平台上取得成功吗?
double* d = calloc(1, sizeof(double));
assert(*d == 0.0);
free(d);
Run Code Online (Sandbox Code Playgroud) 我有以下简单的程序来测试 cudaMemset
#include <iostream>
#include <cuda.h>
using namespace std;
__global__ void kernel(int *input){
input[threadIdx.x] += threadIdx.x;
}
int main() {
size_t size = 5;
int *h_ptr, *d_ptr;
h_ptr = new int[size];
cudaMalloc((void **)&d_ptr, sizeof(int) * size);
cudaMemset(d_ptr, 10, sizeof(int) * size);
kernel<<<1, size>>>(d_ptr);
cudaDeviceSynchronize();
cudaMemcpy(h_ptr, d_ptr, sizeof(int)*size, cudaMemcpyDeviceToHost);
for(int i = 0; i < size; i++)
cout<<h_ptr[i]<<" ";
cout<<endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我预计结果将是[10 11 12 13 14]
我得到垃圾值.
我错过了什么?
谢谢!
(我引用的是ISO/IEC 9899:201x)
在这里我们看到,整数常量表达式具有整数类型:
6.6常量表达式
6. 整数常量表达式应具有整数类型,并且只能具有整数常量的操作数,枚举常量,字符常量,结果为整数常量的sizeof表达式,_Alignof表达式以及作为强制转换的直接操作数的浮点常量.整数常量表达式中的转换运算符只能将算术类型转换为整数类型,除非作为sizeof或_Alignof运算符的操作数的一部分.
这适用于任何整数类型:
6.2.6.2整数类型
5.未指定任何填充位的值.符号位为零的有符号整数类型的有效(非陷阱)对象表示是相应无符号类型的有效对象表示,并且应表示相同的值.对于任何整数类型,所有位为零的对象表示应该是该类型中零值的表示.
然后我们看到使用值为0的整数常量表达式定义空指针常量.
6.3.2.3指针
3. 值为0的整型常量表达式或类型为void*的表达式称为空指针常量.如果将空指针常量转换为指针类型,则保证将结果指针(称为空指针)与指向任何对象或函数的指针进行比较.
因此,空指针常量必须将其所有位设置为零.
但是在线和StackOverflow上有很多答案说这不是真的.
给出引用的部分,我很难相信他们.
(请使用最新标准的参考答案)
这是代码:
#include <iostream>
#include <cstring>
int main()
{
int win[11];
std::memset(win, 1, sizeof(win));
for (int i = 0; i < 11; ++i)
std::cout << win[i] << ' ';
std::cout << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我认为这里没有逻辑缺陷?但是1
,我没有得到一串印刷品16843009
.
如果我改变memset
为std::memset(win, 0, sizeof(win))
.然后一切都如预期.胜利的内容全是零.
我在这里错过了什么吗?
我使用g++ 4.7.3
的Ubuntu 13.04
.
对不起这个重复的问题.
这是答案.谢谢