C 不使用sizeof查找大小

C 不使用sizeof查找大小,c,sizeof,C,Sizeof,我理解,我们可以使用以下方法找到特定类型指针的大小: printf("size of an int pointer: %d", sizeof(int*)); printf("size of a float pointer: %d", sizeof(float*)); printf("size of pointer to void: %d", sizeof(void*)); 在C中,是否可以在不使用sizeof的情况下查找结构的大小?是的,我们可以执行以下操作来查找结构的大小,而不使用sizeo

我理解,我们可以使用以下方法找到特定类型指针的大小:

printf("size of an int pointer: %d", sizeof(int*));
printf("size of a float pointer: %d", sizeof(float*));
printf("size of pointer to void: %d", sizeof(void*));

在C中,是否可以在不使用sizeof的情况下查找结构的大小?

是的,我们可以执行以下操作来查找结构的大小,而不使用sizeof:


执行指针运算并测量步长

#include <stdio.h>
struct foo { char a[5],b[98];};

#define SYZEOV(t) ((size_t)((void*)(((t*)(NULL))+1)-NULL))


int main(int m, char**n){
  printf("sizeexpr=%ld\n", (long)((void*)(((struct foo*)(NULL))+1)-NULL));
  printf("syzeov  =%ld\n", (long)SYZEOV(struct foo));
  printf("sizeof  =%ld\n", (long)sizeof(struct foo));
  return 0;
};

简言之,你不能。有些人建议使用指针算法,就像你在回答中所做的那样,以及使用宏来生成sizeof运算符。原因是数据类型的大小只有机器的编译器知道。指针算法在幕后使用sizeof运算符。

C的设计方式是,sizeof始终返回指针增量(以字节为单位)以移动到下一个数组元素,因此sizeoftype[N]==N*sizeoftype始终为真

那么你可以选择使用其中一种

然后,sizeof和pointer increment都不会返回操作数的大小,相反,它们都会返回当它们成为数组时每个对象占用的内存量

尝试以下方法:

struct myStruct
{
   double a;
   char b;
}
struct myBigStruct
{
   struct myStruct small;
   char b;
}
那么sizeofstruct myStruct很可能是2*sizeofdouble,而不是sizeofdouble+sizeofchar,因为在创建myStruct数组时,下一个数组元素必须离得那么远

myStruct真的占用了那么多空间吗?可能不会

如果您执行以下操作:

struct myStruct
{
   double a;
   char b;
}
struct myBigStruct
{
   struct myStruct small;
   char b;
}
那么sizeofstruct myBigStruct很可能仍然是2*sizeofdouble,而不是sizeofstruct myStruct+sizeofchar

所有这些都依赖于实现


这只是因为太多的人假设sizeoftype[N]==N*sizeoftype,所以C通过这样设置sizeof来强制它为真。

Afaik,反正它使用sizeof来执行++结构指针,那么为什么不直接使用它呢?为什么要问一个问题并自己回答?指针2-指针1返回一个ptrdiff_t,它不是用%d格式字符串表示的。编译器必须知道结构的大小,这样它就知道在执行++structPointer时指针要增加多少。@user1320881为什么要问一个问题并自己回答?->@user1320881:不,它在内部不使用sizeof运算符。为什么需要这样做?使用sizeof有什么不对?@Barmar它只是为了教育目的。sizeof没有问题。谢谢。首先你应该使用%zu@Jack:对于大多数实现来说,这是正确的,但C标准肯定不能保证这一点。例如,在字寻址系统中,int*可能是一个字,而char*可能需要额外的偏移量来标识字中的字节。@杰克:是的,有很多错误信息。建议放弃长强制转换并使用%jd。@chux您凭什么认为ptrdiff_t与intmax_t相同?我的错误,对于intmax\u t,不是%jd,但建议删除长强制转换并使用%td,因为指针差异是ptrdiff\u t类型。如果系统不支持%td,则转换为intmax_t并使用%jd。IAC-nice回答了调用未定义行为的几个问题:nice,还可以使用void*&m+1-void*&m为变量生成宏:sizeofm,但我无法想象sizeof1是如何实现的。不,指针算法在幕后没有使用sizeof操作符。指针算术和sizeof运算符的结果都取决于操作数或指向对象的大小。sizeof不是函数,不调用,也不返回编译器指令