据我所知,
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");
}
}
据我了解,
可以[分配]给NAN
类型变量double
说的对。
NaN
是为基于 IEEE-754 的类型(如 float
和 double
)定义的特殊值之一。1
但不一定
/int
size_t
对。
NaN
是 not 为整数类型 int
或 size_t
定义的值。
您不能将
NaN
存储在一个整数变量中,原因与您不能将 3.14 存储在一个整数变量中的原因相同。它只是不是整数类型可以容纳的值之一。
(编程中 数据类型 的正式定义之一是它是一组值,以及对这些值的一组操作。对于类型
float
和 double
— 但仅适用于这些类型—NaN
是其中一个值。实际上,有多个NaN
值,但那是另一回事。)
对于浮点类型,
NaN
s 是 哨兵值,定义明确的“非值”值。有些类型有哨兵值,有些则没有。例如,对于指针类型,NULL
是标记“不是有效指针”值。在 C 字符串中,空字符 \0
是标记字符串结尾的标记值。另一方面,当您调用 getchar
时,EOF
是“不是字符”值。 (不过,这不会使 EOF
成为 char
类型的标记值,因为 EOF
不是 char
类型的值。)
但是对于任何其他整数类型都没有预定义的标记值。整数在实际程序中的使用方式,没有任何值可以保留为可能也不是有效值的标记。
如果你有一个整数变量并且你需要一个标记值,你将需要定义一个你自己的,如果可以的话。例如,如果您知道您的值始终为正,则可以使用 -1 作为标记值。但这充其量只是一个约定:值 -1 不会被语言或 CPU 特殊对待——它只是另一个整数值。
浮点数和指针类型具有标记值是很棒的,但有时其他类型没有标记值是一件令人讨厌的事情。在尝试为其他类型定义标记值时必须使用的 ad hoc 约定经常会导致各种麻烦。为了使
EOF
作为 getchar
的标记值,程序员必须记住 始终将 getchar
的返回值存储在 int
类型的变量中,而不是 char
。像 read
这样的函数返回读取的字符数,或 -1 表示错误,很难为其定义一个好的返回类型,因为它必须被签名以适应 -1,但否则可能是无符号的.2 函数 mktime
将分解的时间结构转换回完整的 time_t
值,返回 -1 表示错误,这意味着您无法明确判断是否出现错误,或成功转换时间为1969年12月31日23:59:59
脚注 1:根据 C 中的 IEEE-754 定义,
float
和 double
类型并非necessarily,但在如今的大多数系统上,它们是。
脚注 2:我认为这就是为什么
read
被定义为返回类型 ssize_t
的值,我相信类型 ssize_t
是一个“带符号的 size_t
”,或者换句话说,“一个值否则会是无符号的,就像 size_t
一样,只是它必须被签名才能返回 -1"。