Actually when a datatype, say int
is stored in a string or a character array, and the string is passed as an argument to sizeof operator, the program returns the character array size instead of substituting the actual data type that is stored in the string, as an argument.
实际上,当数据类型,比如int存储在字符串或字符数组中,并且字符串作为参数传递给sizeof运算符时,程序返回字符数组大小而不是替换存储在字符串中的实际数据类型,作为一个论点。
So is it possible in anyway to substitute the content of the string as an argument instead?
那么无论如何都可以将字符串的内容替换为参数呢?
Here's the code in c
这是c中的代码
#include <stdio.h>
int main()
{
char s[20];
printf("Please enter the data type to find it's size!: ");
scanf("%s",&s);
printf("The size of %s data type in c language is: %d",s,sizeof(s));
return 0;
}
4 个解决方案
#1
1
No, that’s not possible. There’s no more type information in your program after it’s compiled (of course, there might be debugging information, but I doubt you wanna use that).
不,那是不可能的。在编译之后,程序中没有更多的类型信息(当然,可能有调试信息,但我怀疑你想要使用它)。
One thing you could do, is create a large if statement:
你可以做的一件事是创建一个大的if语句:
// ...
scanf("%s",&s);
size_t size;
if (strcmp(s, "int") == 0) {
size = sizeof(int);
}
else if (strcmp(s, "short") == 0) {
size = sizeof(short);
}
// ... all other types you wanna support
else {
printf("Did not recognize type %s\n", s);
return 1;
}
printf("The size of %s data type in c language is: %d ",s,size);
This way you retrieve all type information at compile time, store it in your program explicitly and you can therefore access it.
这样,您可以在编译时检索所有类型信息,并将其明确存储在程序中,因此您可以访问它。
#2
2
First of all, sizeof
is a compile-time operator. Except for VLAs as argument, the operation happens at compile-time, so you cannot modify the argument in run-time and expect it to work magically.
首先,sizeof是一个编译时运算符。除了作为参数的VLA之外,操作在编译时发生,因此您无法在运行时修改参数并期望它可以神奇地工作。
That said, even it would have been possible to evaluate at run-time, it won't make sense, because in a compiled program, the datatype does not (need to) exist anymore. Compiler allocates memory (map) based on the data types and there ends the existence of the data types. It does not live in a binary so your program has no notion of int
or short
.
也就是说,即使它可以在运行时进行评估,也没有意义,因为在编译的程序中,数据类型不再(需要)存在。编译器根据数据类型分配内存(map),并结束数据类型的存在。它不是二进制文件,所以你的程序没有int或short的概念。
The best you can do is, have a list of available / allowed type / variables, compare the input for a matched type and then, return the result of applying sizeof
operator on that variable / type.
您可以做的最好的事情是,有一个可用/允许的类型/变量列表,比较匹配类型的输入,然后返回在该变量/类型上应用sizeof运算符的结果。
Last but not the least, sizeof
produces a result of type size_t
, you must use %zu
format specifier to print the result.
最后但并非最不重要,sizeof生成类型size_t的结果,您必须使用%zu格式说明符来打印结果。
#3
1
No. The sizeof
operator works directly on types and variables. There is no way to use a variable to refer to a type, and have sizeof
operate on the type referred to by the variable.
不。sizeof运算符直接用于类型和变量。无法使用变量来引用类型,并且sizeof对变量引用的类型进行操作。
The way you can implement a size query program, is to create an array of supported types, and their sizes, and query that:
实现大小查询程序的方法是创建受支持类型的数组及其大小,并查询:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
typedef struct {
const char *const name;
const size_t size;
} type_spec;
const type_spec known_types[] = {
{ "char", sizeof (char) }, /* Always 1 */
{ "signed char", sizeof (signed char) }, /* Always 1 */
{ "unsigned char", sizeof (unsigned char) }, /* Always 1 */
{ "short", sizeof (short) },
{ "signed short", sizeof (signed short) },
{ "unsigned short", sizeof (unsigned short) },
{ "int", sizeof (int) },
{ "signed int", sizeof (signed int) },
{ "unsigned int", sizeof (unsigned int) },
{ "long", sizeof (long) },
{ "signed long", sizeof (signed long) },
{ "unsigned long", sizeof (unsigned long) },
{ "size_t", sizeof (size_t) },
{ "off_t", sizeof (off_t) },
{ "time_t", sizeof (time_t) },
{ "float", sizeof (float) },
{ "double", sizeof (double) },
/* End of array terminator */
{ NULL, 0 }
};
size_t size_of(const char *name)
{
size_t i;
for (i = 0; known_types[i].name != NULL; i++)
if (!strcmp(name, known_types[i].name))
return known_types[i].size;
/* Unknown type name, return 0 */
return 0;
}
void list_all_types(FILE *out)
{
size_t i;
for (i = 0; known_types[i].name != NULL; i++)
fprintf(out, "sizeof (%s) == %zu\n",
known_types[i].name,
known_types[i].size);
}
Note that because the type names can contain spaces, I would not use scanf()
to read them. I would simply have the user specify the type or types on the command line, instead:
请注意,因为类型名称可以包含空格,所以我不会使用scanf()来读取它们。我只想让用户在命令行中指定一个或多个类型,而不是:
int main(int argc, char *argv[])
{
size_t size;
int arg;
if (argc < 2) {
list_all_types(stdout);
return EXIT_SUCCESS;
}
if (!strcmp(argv[1], "-l") || !strcmp(argv[1], "--list")) {
list_all_types(stdout);
return EXIT_SUCCESS;
}
if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) {
printf("\n");
printf("Usage: %s -h | --help\n", argv[0]);
printf(" %s [ -l | --list ]\n", argv[0]);
printf(" %s type [ type ... ]\n", argv[0]);
printf("\n");
printf("This program reports the sizes of most basic\n");
printf("types supported in C.\n");
printf("\n");
return EXIT_SUCCESS;
}
for (arg = 1; arg < argc; arg++) {
size = size_of(argv[arg]);
if (!size) {
fflush(stdout);
fprintf(stderr, "%s: unsupported type.\n", argv[arg]);
return EXIT_FAILURE;
}
printf("sizeof (%s) == %zu\n", argv[arg], size);
}
return EXIT_SUCCESS;
}
The list in the known_types
array is not exhaustive, but you can add any types you want to the array trivially, one line per type. .
known_types数组中的列表并不详尽,但您可以简单地向阵列添加任何类型的类型,每种类型一行。 。
#4
0
You can generate a C program, compile it and run it. Something like this:
您可以生成C程序,编译并运行它。像这样的东西:
char mytype[100] = "unsigned long long int";
int mysize;
// start the compiler
FILE *f = popen("gcc -x c -o test -", "w");
// generate the program to compile
fprintf(f, "int main(){return sizeof(%s);}", mytype);
// wait for the compiler to finish
mysize = pclose(f);
// run the compiled program and get its exit code
mysize = WEXITSTATUS(system("./test"));
// cleanup - delete the executable
remove("test");
printf("Size of %s is %d\n", mytype, mysize);
This is more trouble than it's worth - too many places where it could go wrong (no gcc installed on the system; current directory not writable; etc).
这比它的价值更麻烦 - 太多可能出错的地方(系统上没有安装gcc;当前目录不可写;等等)。
#1
1
No, that’s not possible. There’s no more type information in your program after it’s compiled (of course, there might be debugging information, but I doubt you wanna use that).
不,那是不可能的。在编译之后,程序中没有更多的类型信息(当然,可能有调试信息,但我怀疑你想要使用它)。
One thing you could do, is create a large if statement:
你可以做的一件事是创建一个大的if语句:
// ...
scanf("%s",&s);
size_t size;
if (strcmp(s, "int") == 0) {
size = sizeof(int);
}
else if (strcmp(s, "short") == 0) {
size = sizeof(short);
}
// ... all other types you wanna support
else {
printf("Did not recognize type %s\n", s);
return 1;
}
printf("The size of %s data type in c language is: %d ",s,size);
This way you retrieve all type information at compile time, store it in your program explicitly and you can therefore access it.
这样,您可以在编译时检索所有类型信息,并将其明确存储在程序中,因此您可以访问它。
#2
2
First of all, sizeof
is a compile-time operator. Except for VLAs as argument, the operation happens at compile-time, so you cannot modify the argument in run-time and expect it to work magically.
首先,sizeof是一个编译时运算符。除了作为参数的VLA之外,操作在编译时发生,因此您无法在运行时修改参数并期望它可以神奇地工作。
That said, even it would have been possible to evaluate at run-time, it won't make sense, because in a compiled program, the datatype does not (need to) exist anymore. Compiler allocates memory (map) based on the data types and there ends the existence of the data types. It does not live in a binary so your program has no notion of int
or short
.
也就是说,即使它可以在运行时进行评估,也没有意义,因为在编译的程序中,数据类型不再(需要)存在。编译器根据数据类型分配内存(map),并结束数据类型的存在。它不是二进制文件,所以你的程序没有int或short的概念。
The best you can do is, have a list of available / allowed type / variables, compare the input for a matched type and then, return the result of applying sizeof
operator on that variable / type.
您可以做的最好的事情是,有一个可用/允许的类型/变量列表,比较匹配类型的输入,然后返回在该变量/类型上应用sizeof运算符的结果。
Last but not the least, sizeof
produces a result of type size_t
, you must use %zu
format specifier to print the result.
最后但并非最不重要,sizeof生成类型size_t的结果,您必须使用%zu格式说明符来打印结果。
#3
1
No. The sizeof
operator works directly on types and variables. There is no way to use a variable to refer to a type, and have sizeof
operate on the type referred to by the variable.
不。sizeof运算符直接用于类型和变量。无法使用变量来引用类型,并且sizeof对变量引用的类型进行操作。
The way you can implement a size query program, is to create an array of supported types, and their sizes, and query that:
实现大小查询程序的方法是创建受支持类型的数组及其大小,并查询:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
typedef struct {
const char *const name;
const size_t size;
} type_spec;
const type_spec known_types[] = {
{ "char", sizeof (char) }, /* Always 1 */
{ "signed char", sizeof (signed char) }, /* Always 1 */
{ "unsigned char", sizeof (unsigned char) }, /* Always 1 */
{ "short", sizeof (short) },
{ "signed short", sizeof (signed short) },
{ "unsigned short", sizeof (unsigned short) },
{ "int", sizeof (int) },
{ "signed int", sizeof (signed int) },
{ "unsigned int", sizeof (unsigned int) },
{ "long", sizeof (long) },
{ "signed long", sizeof (signed long) },
{ "unsigned long", sizeof (unsigned long) },
{ "size_t", sizeof (size_t) },
{ "off_t", sizeof (off_t) },
{ "time_t", sizeof (time_t) },
{ "float", sizeof (float) },
{ "double", sizeof (double) },
/* End of array terminator */
{ NULL, 0 }
};
size_t size_of(const char *name)
{
size_t i;
for (i = 0; known_types[i].name != NULL; i++)
if (!strcmp(name, known_types[i].name))
return known_types[i].size;
/* Unknown type name, return 0 */
return 0;
}
void list_all_types(FILE *out)
{
size_t i;
for (i = 0; known_types[i].name != NULL; i++)
fprintf(out, "sizeof (%s) == %zu\n",
known_types[i].name,
known_types[i].size);
}
Note that because the type names can contain spaces, I would not use scanf()
to read them. I would simply have the user specify the type or types on the command line, instead:
请注意,因为类型名称可以包含空格,所以我不会使用scanf()来读取它们。我只想让用户在命令行中指定一个或多个类型,而不是:
int main(int argc, char *argv[])
{
size_t size;
int arg;
if (argc < 2) {
list_all_types(stdout);
return EXIT_SUCCESS;
}
if (!strcmp(argv[1], "-l") || !strcmp(argv[1], "--list")) {
list_all_types(stdout);
return EXIT_SUCCESS;
}
if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) {
printf("\n");
printf("Usage: %s -h | --help\n", argv[0]);
printf(" %s [ -l | --list ]\n", argv[0]);
printf(" %s type [ type ... ]\n", argv[0]);
printf("\n");
printf("This program reports the sizes of most basic\n");
printf("types supported in C.\n");
printf("\n");
return EXIT_SUCCESS;
}
for (arg = 1; arg < argc; arg++) {
size = size_of(argv[arg]);
if (!size) {
fflush(stdout);
fprintf(stderr, "%s: unsupported type.\n", argv[arg]);
return EXIT_FAILURE;
}
printf("sizeof (%s) == %zu\n", argv[arg], size);
}
return EXIT_SUCCESS;
}
The list in the known_types
array is not exhaustive, but you can add any types you want to the array trivially, one line per type. .
known_types数组中的列表并不详尽,但您可以简单地向阵列添加任何类型的类型,每种类型一行。 。
#4
0
You can generate a C program, compile it and run it. Something like this:
您可以生成C程序,编译并运行它。像这样的东西:
char mytype[100] = "unsigned long long int";
int mysize;
// start the compiler
FILE *f = popen("gcc -x c -o test -", "w");
// generate the program to compile
fprintf(f, "int main(){return sizeof(%s);}", mytype);
// wait for the compiler to finish
mysize = pclose(f);
// run the compiled program and get its exit code
mysize = WEXITSTATUS(system("./test"));
// cleanup - delete the executable
remove("test");
printf("Size of %s is %d\n", mytype, mysize);
This is more trouble than it's worth - too many places where it could go wrong (no gcc installed on the system; current directory not writable; etc).
这比它的价值更麻烦 - 太多可能出错的地方(系统上没有安装gcc;当前目录不可写;等等)。