英文:
How to populate a vector / matrix of int / size_t with NAN in C
问题
根据我理解,NAN
可以分配给 double
类型的变量,但不一定适用于 int
/ size_t
类型。
是否仍然有一种方法可以用 NAN
来填充 int
/ size_t
类型的向量/矩阵?
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
typedef struct {
size_t nrows, ncols;
size_t *array;
} Matrix ;
size_t ncol = 5;
size_t nrow = 1;
void print_matrix(Matrix * matrix);
int main()
{
Matrix *mat1 = (Matrix *) malloc(sizeof(Matrix));
mat1->nrows = nrow;
mat1->ncols = ncol;
mat1->array = (size_t *) malloc(mat1->nrows * mat1->ncols * sizeof(*mat1->array));
if (mat1 == NULL)
{
printf("Could not allocate memory\n");
exit(EXIT_FAILURE);
}
else
{
mat1->nrows = nrow;
mat1->ncols = ncol;
mat1->array = (size_t *) malloc(mat1->nrows * mat1->ncols * sizeof(*mat1->array));
for (size_t row =0; row<mat1->nrows; row++)
{
for (size_t col =0; col<mat1->ncols; col++)
{
mat1->array[row * ncol + col] = NAN;
}
}
print_matrix(mat1);
free(mat1);
}
}
void print_matrix(Matrix * matrix)
{
for (size_t row =0; row<matrix->nrows; row++)
{
for (size_t col =0; col<matrix->ncols; col++)
{
printf("%zu ", matrix->array[row * ncol + col]);
}
printf("\n");
}
}
英文:
As far as I understood, NAN
can be allocate to a double
type variable but not necessarily to int
/ size_t
Is there still a way to populate a vector/matrix of type int
/ size_t
with NAN?
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
typedef struct {
size_t nrows, ncols;
size_t *array;
} Matrix ;
size_t ncol = 5;
size_t nrow = 1;
void print_matrix(Matrix * matrix);
int main()
{
Matrix *mat1 = (Matrix *) malloc(sizeof(Matrix));
mat1->nrows = nrow;
mat1->ncols = ncol;
mat1->array = (size_t *) malloc(mat1->nrows * mat1->ncols * sizeof(*mat1->array));
if (mat1 == NULL)
{
printf("Could not allocate memory\n");
exit(EXIT_FAILURE);
}
else
{
mat1->nrows = nrow;
mat1->ncols = ncol;
mat1->array = (size_t *) malloc(mat1->nrows * mat1->ncols * sizeof(*mat1->array));
for (size_t row =0; row<mat1->nrows; row++)
{
for (size_t col =0; col<mat1->ncols; col++)
{
mat1->array[row * ncol + col] = NAN;
}
}
print_matrix(mat1);
free(mat1);
}
}
void print_matrix(Matrix * matrix)
{
for (size_t row =0; row<matrix->nrows; row++)
{
for (size_t col =0; col<matrix->ncols; col++)
{
printf("%zu ", matrix->array[row * ncol + col]);
}
printf("\n");
}
}
答案1
得分: 4
As far as I understood,
NAN
can be [assigned] to adouble
type variable
根据我的理解,NAN
可以分配给 double
类型的变量。
That is correct. NaN
is one of the special values defined for IEEE-754-based types like float
and double
.<sup>1</sup>
这是正确的。NaN
是在 IEEE-754 基础类型,如 float
和 double
中定义的特殊值之一。
but not necessarily to
int
/size_t
但不一定可以分配给 int
或 size_t
。
Right. NaN
is not a value defined for integral types int
or size_t
.
正确。NaN
不 是对整数类型 int
或 size_t
定义的值之一。
You can't store NaN
in an integral variable for the same reason you can't store 3.14 in an integral variable. It's just not one of the values that integral types can hold.
你不能将 NaN
存储在整数变量中,原因与你不能将 3.14 存储在整数变量中相同。这不是整数类型可以保存的值之一。
(One of the formal definitions of a data type in programming is that it is a set of values, and a set of operations on those values. For types float
and double
— but only for those types — NaN
is one of the values. Actually, there are multiple NaN
values, but that's a different story.)
在编程中,数据类型 的正式定义之一是它是一组值,以及对这些值的一组操作。对于 float
和 double
类型 - 但仅限于这些类型 - NaN
是其中的一个值。实际上,存在多个 NaN
值,但这是另一回事。
For the floating-point types, NaN
s are sentinel values, well-defined "not a value" values. Some types have sentinel values, and some don't. For example, for pointer types, NULL
is the sentinel "not a valid pointer" value. In C strings, the null character \0
is a sentinel value marking the end of the string. On the other hand, when you call getchar
, EOF
is the "not a character" value. (This doesn't make EOF
a sentinel value for type char
, though, since EOF
is not a value of type char
.)
对于浮点类型,NaN
是哨兵值,明确定义的“不是一个值”的值。某些类型具有哨兵值,而某些类型则没有。例如,对于指针类型,NULL
是哨兵值,表示“无效指针”值。在C字符串中,空字符\0
是表示字符串末尾的哨兵值。另一方面,当调用 getchar
时,EOF
是“不是字符”的值。(这并不使EOF
成为 char
类型的哨兵值,因为 EOF
不是 char
类型的值。)
But there is no predefined sentinel value for any of the other integral types. The way integers are used in real programs, there's no value that could be reserved as a sentinel that might not also be a valid value.
但是,对于其他整数类型,没有预定义的哨兵值。在实际程序中使用整数的方式,没有可以保留为哨兵的值,这个值可能也是有效值。
If you have an integer variable and you need a sentinel value, you will need to define one of your own, if you can. For example, if you know that your values are always positive, you can use -1 as a sentinel value. But this will be, at best, a convention: the value -1 won't be treated specially by the language, or the CPU — it's just another integer value.
如果你有一个整数变量并且需要一个哨兵值,如果可以的话,你需要自己定义一个。例如,如果你知道你的值始终为正,你可以使用 -1 作为哨兵值。但这最多只是一个约定:值 -1 不会被编程语言或CPU特殊对待 - 它只是另一个整数值。
It's great that floating-point and pointer types have sentinel values, and it's sometimes a nuisance that other types don't. The ad hoc conventions one has to use when trying to define sentinel values for other types frequently lead to various nuisances. In order for EOF
to work as a sentinel value for getchar
, programmers have to remember to always store getchar
's return value in a variable of type int
, not char
. A function like read
that returns a number of characters read, or -1 to indicate an error, is difficult to define a good return type for, since it has to be signed to accommodate -1, but could otherwise be unsigned.<sup>2</sup> The function mktime
, which converts a broken-down time structure back to an integral time_t
value, returns -1 for error, meaning you can't unambiguously tell whether you've gotten an error, or have successfully converted the time 23:59:59 on December 31, 1969.
很好,浮点数和指针类型具有哨兵值,但其他类型没有时有时可能会让人感到不便。在尝试为其他类型定义哨兵值时,必须使用临时约定,这经常会导致各种不便。为了使 EOF
作为 getchar
的哨兵值工作,程序员必须记住[始
英文:
> As far as I understood, NAN
can be [assigned] to a double
type variable
That is correct. NaN
is one of the special values defined for IEEE-754-based types like float
and double
.<sup>1</sup>
> but not necessarily to int
/ size_t
Right. NaN
is not a value defined for integral types int
or size_t
.
You can't store NaN
in an integral variable for the same reason you can't store 3.14 in an integral variable. It's just not one of the values that integral types can hold.
(One of the formal definitions of a data type in programming is that it is a set of values, and a set of operations on those values. For types float
and double
— but only for those types — NaN
is one of the values. Actually, there are multiple NaN
values, but that's a different story.)
For the floating-point types, NaN
s are sentinel values, well-defined "not a value" values. Some types have sentinel values, and some don't. For example, for pointer types, NULL
is the sentinel "not a valid pointer" value. In C strings, the null character \0
is a sentinel value marking the end of the string. On the other hand, when you call getchar
, EOF
is the "not a character" value. (This doesn't make EOF
a sentinel value for type char
, though, since EOF
is not a value of type char
.)
But there is no predefined sentinel value for any of the other integral types. The way integers are used in real programs, there's no value that could be reserved as a sentinel that might not also be a valid value.
If you have an integer variable and you need a sentinel value, you will need to define one of your own, if you can. For example, if you know that your values are always positive, you can use -1 as a sentinel value. But this will be, at best, a convention: the value -1 won't be treated specially by the language, or the CPU — it's just another integer value.
It's great that floating-point and pointer types have sentinel values, and it's sometimes a nuisance that other types don't. The ad hoc conventions one has to use when trying to define sentinel values for other types frequently lead to various nuisances. In order for EOF
to work as a sentinel value for getchar
, programmers have to remember to always store getchar
's return value in a variable of type int
, not char
. A function like read
that returns a number of characters read, or -1 to indicate an error, is difficult to define a good return type for, since it has to be signed to accommodate -1, but could otherwise be unsigned.<sup>2</sup> The function mktime
, which converts a broken-down time structure back to an integral time_t
value, returns -1 for error, meaning you can't unambiguously tell whether you've gotten an error, or have successfully converted the time 23:59:59 on December 31, 1969.
Footnote 1: Types float
and double
aren't necessarily based on the IEEE-754 definitions in C, but on most systems these days, they are.
Footnote 2: I believe that's why read
is defined as returning a value of type ssize_t
, and I believe type ssize_t
is a "signed size_t
", or in other words, "A value that would otherwise be unsigned, just like size_t
is, except it has to be signed so it can return -1".
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论