C、memset a double 数组失败
C, memset a double array failed
我想动态声明一个double
类型的数组,所以这是我的代码
void function(int length, ...)
{
...
double *a = malloc(sizeof(double) * length);
memset(a, 1, sizeof(double) * length);
for (int i = 0; i < length; i++)
{
printf("%f", a[i]);
}
...
}
当我传递 2
的 length
时,代码不会打印全 1。它只打印以下内容:
7.7486e-304
7.7486e-304
那么,我应该怎么做才能解决它?
memset
设置字节。您正在尝试设置双打。只需从 0
循环到 length
并将每个设置为 1.0
:
for (int i = 0; i < length; i ++)
{
a[i] = 1; // or 1.0 if you want to be explicit
}
memset
将数组的每个字节设置为 1
而不是每个 int
或 double
元素。
您正在尝试设置 double
值(可能为 8 个或更多字节)。您的方法仅适用于数字 0.0
,因为它恰好用所有字节表示 0
在使用 IEEE-754 浮点格式的系统上。请注意,这将是不可移植的,因为 C 标准允许浮点值的其他表示。
如果 a
指向整数数组,您的方法将适用于 0
和 -1
以及一些特殊值,例如 0x01010101
... 但是它仍然是一种不可移植的方法,因为它会失败,甚至会在具有填充位或非 2s 补码整数表示的奇异体系结构上调用未定义的行为。
初始化数组的正确方法是像这样的显式循环:
for (int i = 0; i < length; i++) {
a[i] = 1.0;
}
编译器可能会将此循环编译成非常高效的代码。
您混淆了设置数组和设置存储数组的底层内存。
一个double由8个字节组成。您正在将构成双精度数的每个字节设置为 1。
如果你想将数组的每个元素初始化为 1.0,那么你可以使用 for(;;) 循环,或者因为你似乎在使用 C++,你可以使用容器并使用构造函数来初始化每个元素(如果构造函数有能力的话)或者用算法达到同样的效果。
memset
一次设置1个字节。因此,我建议您使用自定义函数将任何数据类型的数组设置为有效值,如下所示:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void *g_memset(void *dst, void *val, size_t valSize, size_t count);
int main(void)
{
double x = 1.0;
double Array[50];
g_memset(Array, &x, sizeof(x), 20); /* set the 1st 20 elements to 1.0 */
for (int n = 0; n < 20; n++) {
printf("%.1lf ", Array[n]);
}
putchar('\n');
return 0;
}
void *g_memset(void *dst, void *val, size_t valSize, size_t count)
{
char *ptr = (char *)dst;
while (count-- > 0) {
memcpy(ptr, val, valSize);
ptr += valSize;
}
return dst;
}
你使用memset
来设置数组a
的每个字节。双变量是8个字节,在memset
数组a
之后每个字节是1。
函数 memset
用于 char
数组。
如果你想初始化你的数组 a
你可以使用循环(while/for).
int j;
for(j = 0;i < length;j++)
a[j] = 1;
我想动态声明一个double
类型的数组,所以这是我的代码
void function(int length, ...)
{
...
double *a = malloc(sizeof(double) * length);
memset(a, 1, sizeof(double) * length);
for (int i = 0; i < length; i++)
{
printf("%f", a[i]);
}
...
}
当我传递 2
的 length
时,代码不会打印全 1。它只打印以下内容:
7.7486e-304
7.7486e-304
那么,我应该怎么做才能解决它?
memset
设置字节。您正在尝试设置双打。只需从 0
循环到 length
并将每个设置为 1.0
:
for (int i = 0; i < length; i ++)
{
a[i] = 1; // or 1.0 if you want to be explicit
}
memset
将数组的每个字节设置为 1
而不是每个 int
或 double
元素。
您正在尝试设置 double
值(可能为 8 个或更多字节)。您的方法仅适用于数字 0.0
,因为它恰好用所有字节表示 0
在使用 IEEE-754 浮点格式的系统上。请注意,这将是不可移植的,因为 C 标准允许浮点值的其他表示。
如果 a
指向整数数组,您的方法将适用于 0
和 -1
以及一些特殊值,例如 0x01010101
... 但是它仍然是一种不可移植的方法,因为它会失败,甚至会在具有填充位或非 2s 补码整数表示的奇异体系结构上调用未定义的行为。
初始化数组的正确方法是像这样的显式循环:
for (int i = 0; i < length; i++) {
a[i] = 1.0;
}
编译器可能会将此循环编译成非常高效的代码。
您混淆了设置数组和设置存储数组的底层内存。
一个double由8个字节组成。您正在将构成双精度数的每个字节设置为 1。
如果你想将数组的每个元素初始化为 1.0,那么你可以使用 for(;;) 循环,或者因为你似乎在使用 C++,你可以使用容器并使用构造函数来初始化每个元素(如果构造函数有能力的话)或者用算法达到同样的效果。
memset
一次设置1个字节。因此,我建议您使用自定义函数将任何数据类型的数组设置为有效值,如下所示:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void *g_memset(void *dst, void *val, size_t valSize, size_t count);
int main(void)
{
double x = 1.0;
double Array[50];
g_memset(Array, &x, sizeof(x), 20); /* set the 1st 20 elements to 1.0 */
for (int n = 0; n < 20; n++) {
printf("%.1lf ", Array[n]);
}
putchar('\n');
return 0;
}
void *g_memset(void *dst, void *val, size_t valSize, size_t count)
{
char *ptr = (char *)dst;
while (count-- > 0) {
memcpy(ptr, val, valSize);
ptr += valSize;
}
return dst;
}
你使用memset
来设置数组a
的每个字节。双变量是8个字节,在memset
数组a
之后每个字节是1。
函数 memset
用于 char
数组。
如果你想初始化你的数组 a
你可以使用循环(while/for).
int j;
for(j = 0;i < length;j++)
a[j] = 1;