C 有等价于 var 的东西吗?

Does C have an equivalent to var?

我想为程序设置一个任意值的变量。我能做的最好的事情就是使用 var,但是 var 关键字在 C 中不存在。

我试过这段代码:

#include <stdio.h>

int main() {
    var a = 2;
    puts(a);
}

然后得到这些错误:

var.c:4:5: error: use of undeclared identifier 'var'
    var a = 2;
    ^
var.c:5:10: error: use of undeclared identifier 'a'
    puts(a);
         ^

如果不是 var,那么它在 C 中的等效项是什么?

用 C 编写的脚本语言设法为其变量实现这一点。然而,它是相当复杂的。

C 需要知道事物的大小,以便它可以将它们正确地放入内存中。变量必须始终是已知类型和大小。

为了拥有一个未知类型的变量,您需要创建一个类似这样的结构(超出我的想象,未经测试,但请参阅 https://github.com/zlynx/type-union-test):

struct var {
    enum {
        INT,
        OBJ,
        DOUBLE,
    };
    union {
        long i;
        void* p;
        double d;
    };
};

然后是对所有东西进行操作的函数。实现 OBJ 变得很有趣,因为您需要更多的结构来定义它是数组还是另一个 var 等等。

总之。如果您希望使用 C 更轻松 进行编程,那么请不要尝试此操作。预先决定你的变量是什么。

能用指针就用void *:

#include <stdio.h>

int main() {
 char *s = "abc";
 void *a = s;
 puts(a);

 return 0;
}

C 是静态类型的。这意味着所有变量都有特定类型,所有函数参数和 return 值都有特定类型。此外,这意味着在分配变量、传递参数或 returning 值时,该值必须匹配指定的类型或 compatible/convertible 符合语言规则的该类型。

这可能看起来很不方便,但 C 是一种系统级语言,能够直接与内存交互,并且 I/O 高效,在系统级语言中,强类型是必不可少的。有大量与支持弱类型语言相关的代码;在 C 中,它只是一个适当且固定大小的内存位置。

在您的示例中,您的变量中有一个整数值 2,但您想使用 puts() 打印一个字符串,该字符串需要一个 char* 参数来引用以 NUL 结尾的字符串。解决此问题的惯用 C 方法是使用一个函数来生成整数值的字符串表示形式。因为 C 不会“神奇地”为您执行该转换,所以它有一个库可以处理最常见的转换和表示要求。在这种情况下:

#include <stdio.h>

int main() 
{
    int a = 2;
    printf( "%d\n", a ) ;
}

在这种情况下,printf() 使用 %d 格式说明符将整数 2 表示为字符串 "2",后跟换行符。字符串“2”是一个代码为 0x32 或 50 十进制(假设 ASCII 编码)的字符。

如果你仍然认为你需要一个变体,(因为在这个例子中很明显它根本没有必要),然后用你试图解决的问题的更具体的例子提出一个新问题 - 你不会有疑问得到答案,说明如何用 C 语言解决问题 - 并非所有解决方案都像这样简单。

正如其他人已经提到的,归根结底,您需要知道变量的类型才能对其进行处理。

除了 void * 指针之外,您还可以 将所有内容都视为 C 字符串 nul-终止的字符缓冲区),然后使用任何C99 strto* 函数族 (float*, signed*, unsigned*) 按需将它们转换为预期类型。

例如,下面将 a 声明为 c 字符串并输出其 floatlong intunsigned long 表示形式:

char *a = "-2.3";
printf( "float: %f\n", strtof(a, NULL) );
printf( "long: %ld\n", strtol(a, NULL, 10) );
printf( "unsigned long: %lu\n", strtoul(a, NULL, 10) );

输出:

float: -2.300000
long: -2
unsigned long: 4294967294

你可以用这些函数做更多花哨的事情(甚至用 void * 指针做更多的事情)但是它们都不能准确回答你的问题,因为 C 不直接支持你的问题。

这两个建议都违背了语言的本质。如果你要使用C,只要学习和使用支持的类型(或者定义你自己的,也很好支持)。