假设我们有 3 个变量:

 char a[4][4];
 char *b[4];
 char **c;

假设上述所有变量都正确分配了值。
没有代码错误。

所有这些变量都可以使用 [] 运算符打印它们的值,如下所示:
for( i=0; i<4; i++){
    printf( "%s\n", a[i] );
}
for( i=0; i<4; i++){
    printf( "%s\n", b[i] );
}
for( i=0; i<4; i++){
    printf( "%s\n", c[i] );

仅查看这些打印语句,无法识别其真正的数据类型。
如何识别其变量数据类型?

我的一个想法是打印出每个索引的内存地址。
对于二维数组,内存地址应该以相等的距离分开。但是对于数组指针,我希望内存地址在空间上彼此不均匀。
有没有更好的方法来找出这些变量的数据类型?

最佳答案



有一种区分类型的方法。
请注意,“二维数组”不是一种类型——更像是一种类型分类。
"double pointers of char"可以认为是 char ** 类型

将对象的地址传递给 _Generic()

#define xtype(X) _Generic((&X), \
    char (*)[4][4]: "char [4][4]", \
    char *(*)[4]  : "char *[4]", \
    char ***      : "char **", \
    char (*)[4]   : "char [4]", \
    char **       : "char *", \
    char *        : "char", \
    default       : "?" \
)

int main(void) {
  char a[4][4];
  char *b[4];
  char **c;
  puts(xtype(a));
  puts(xtype(b));
  puts(xtype(c));
  puts(xtype(a[0]));
  puts(xtype(b[0]));
  puts(xtype(c[0]));
  puts(xtype(a[0][0]));
  puts(xtype(b[0][0]));
  puts(xtype(c[0][0]));
}

输出
char [4][4]
char *[4]
char **
char [4]
char *
char *
char
char
char
_Generic() 是 C 的一个有用补充,它的一些细节和正确应用仍然具有挑战性。我希望以上至少允许 OP 部分区分物体的能力。

有趣的是,我能够使用更通用的 _Generic 如下,在 a,b,c 之间具有相同的可区分性。我对 _Generic 的某些方面持谨慎态度,因为我怀疑是实现定义的行为。
#define xtype(X) _Generic((&X), \
    char (*)[][4] : "char [][4]", \
    char *(*)[]   : "char *[]", \
    char ***      : "char **", \
    char (*)[]    : "char []", \
    char **       : "char *", \
    char *        : "char", \
    default       : "?" \
)

关于c - 如何判断一个变量是二维数组、指针数组还是char的双指针?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/43486612/

10-13 04:58