How to populate a vector / matrix of int / size_t with NAN in C

问题描述 投票:0回答:1

据我所知,

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");
  }
}
c matrix vector integer nan
1个回答
2
投票

据我了解,

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"。

© www.soinside.com 2019 - 2024. All rights reserved.