Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
sizeof(var)是否总是在C中工作?_C_Variables_Sizeof_Binaryfiles - Fatal编程技术网

sizeof(var)是否总是在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); 为什么它有时有效,

每当我想用C读写二进制文件时,我都会使用
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
应用于类型,括号中给出了类型的大小。应用于表达式(不带括号),它给出表达式类型的大小。