sizeof(var)是否总是在C中工作?
每当我想用C读写二进制文件时,我都会使用sizeof(var)是否总是在C中工作?,c,variables,sizeof,binaryfiles,C,Variables,Sizeof,Binaryfiles,每当我想用C读写二进制文件时,我都会使用fread()和fwrite()函数。它们需要读取或写入的数据字节作为参数,因此我使用sizeof()函数。现在的问题是: 书上说我应该声明这样一个函数: fread(&variable,sizeof(TYPE_OF_VAR),quantity,file); 我使用了以下语句,它在大多数情况下都有效,但并不总是有效: fread(&variable,sizeof(VARIABLE),quantity,file); 为什么它有时有效,
fread()
和fwrite()
函数。它们需要读取或写入的数据字节作为参数,因此我使用sizeof()
函数。现在的问题是:
书上说我应该声明这样一个函数:
fread(&variable,sizeof(TYPE_OF_VAR),quantity,file);
我使用了以下语句,它在大多数情况下都有效,但并不总是有效:
fread(&variable,sizeof(VARIABLE),quantity,file);
为什么它有时有效,但有时无效?它是否取决于变量的类型(int、char等)?
它是否取决于我使用的数据量?需要记住的是,
sizeof
基于编译器在编译时对类型的了解(暂时忽略VLA)。如果给它一个变量,它将使用该变量的类型
因此,我唯一能想到它在哪里不能像您期望的那样工作的时间是使用指针
基本上可以归结为:
int x[5];
int *y = &x[0];
int *p = malloc(sizeof(int) * 5);
sizeof(x); // == sizeof(int) * 5
sizeof(y); // == sizeof(int *)
sizeof(p); // == sizeof(int *)
这在处理函数时变得很棘手,因为数组在传递给函数时会衰减到指针。还要注意的是,这三种情况完全相同:
int func(int *p);
int func(int p[5]);
int func(int p[]);
在所有3种类型中,p是一个指针,而不是数组。需要记住的是
sizeof
是基于编译器在编译时对类型的了解(暂时忽略VLA)。如果给它一个变量,它将使用该变量的类型
因此,我唯一能想到它在哪里不能像您期望的那样工作的时间是使用指针
基本上可以归结为:
int x[5];
int *y = &x[0];
int *p = malloc(sizeof(int) * 5);
sizeof(x); // == sizeof(int) * 5
sizeof(y); // == sizeof(int *)
sizeof(p); // == sizeof(int *)
这在处理函数时变得很棘手,因为数组在传递给函数时会衰减到指针。还要注意的是,这三种情况完全相同:
int func(int *p);
int func(int p[5]);
int func(int p[]);
在这三个函数中,p是一个指针,而不是数组。它将始终有效
int main()
{
char a[10];
int b[10];
printf("%d %d %d %d %d %d",sizeof(char),sizeof(int), sizeof(a),sizeof(b), sizeof(a[0]), sizeof(b[0]) );
}
试试上面的代码。您应该看到(根据编译器的不同,我的char为1字节,integer为4字节)1,4,10,40,1,4
对于fread或fwrite或任何您使用它的地方,它都没有什么不同 它将始终有效
int main()
{
char a[10];
int b[10];
printf("%d %d %d %d %d %d",sizeof(char),sizeof(int), sizeof(a),sizeof(b), sizeof(a[0]), sizeof(b[0]) );
}
试试上面的代码。您应该看到(根据编译器的不同,我的char为1字节,integer为4字节)1,4,10,40,1,4
对于fread或fwrite或任何您使用它的地方,它都没有什么不同 有关堆与堆栈的讨论,请参阅此堆栈溢出问题: 堆元素(如指针)上的
sizeof()
将返回指针的大小,而不是指针可以存储的元素数
但是,堆栈元素上的sizeof()
数组或const char*
将返回数组或字符串的长度
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LENGTH 100
int main(int argc, char *argv[])
{
char *a = NULL;
char b[10] = "abcdefghi";
printf("sizeof(b): %zu\n", sizeof(b));
a = malloc(LENGTH + 1);
if (a) {
*(a + LENGTH) = '\0';
memset(a, ' ', LENGTH);
fprintf(stdout, "a (before memcpy):\t[%s]\n", a);
printf("sizeof(a), before: %zu\n", sizeof(a));
memcpy(a, b, sizeof(b) - 1);
fprintf(stdout, "a (after memcpy):\t[%s]\n", a);
printf("sizeof(a), after: %zu\n", sizeof(a));
free(a);
}
return EXIT_SUCCESS;
}
输出:
$ ./sizeofTest
sizeof(b): 10
a (before memcpy): [ ]
sizeof(a), before: 8
a (after memcpy): [abcdefghi ]
sizeof(a), after: 8
在我的平台上,一个
char*
指向一个占用八个字节的内存地址。有关堆与堆栈的讨论,请参阅此堆栈溢出问题:
堆元素(如指针)上的sizeof()
将返回指针的大小,而不是指针可以存储的元素数
但是,堆栈元素上的sizeof()
数组或const char*
将返回数组或字符串的长度
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LENGTH 100
int main(int argc, char *argv[])
{
char *a = NULL;
char b[10] = "abcdefghi";
printf("sizeof(b): %zu\n", sizeof(b));
a = malloc(LENGTH + 1);
if (a) {
*(a + LENGTH) = '\0';
memset(a, ' ', LENGTH);
fprintf(stdout, "a (before memcpy):\t[%s]\n", a);
printf("sizeof(a), before: %zu\n", sizeof(a));
memcpy(a, b, sizeof(b) - 1);
fprintf(stdout, "a (after memcpy):\t[%s]\n", a);
printf("sizeof(a), after: %zu\n", sizeof(a));
free(a);
}
return EXIT_SUCCESS;
}
输出:
$ ./sizeofTest
sizeof(b): 10
a (before memcpy): [ ]
sizeof(a), before: 8
a (after memcpy): [abcdefghi ]
sizeof(a), after: 8
在我的平台上,一个
char*
指向一个占用八个字节的内存地址。你能举一个例子说明这不起作用的时候,包括源代码吗?当标识符(变量)是一个对象时,它起作用;当标识符用于指向对象的指针时,它不起作用。sizeof
应用于类型,括号中给出了类型的大小。应用于表达式,不带括号,它给出了表达式类型的大小。请给出一个示例,说明这不起作用的时间,包括源代码?当标识符(变量)用于对象时,它起作用;当标识符用于指向对象的指针时,它不起作用。sizeof
应用于类型,括号中给出了类型的大小。应用于表达式(不带括号),它给出表达式类型的大小。