c语言 sizeof() 精讲

91 阅读4分钟

sizeof(x) 是关键字,不是函数;在编译时确定其值,不会运行sizeof()括号内的任何代码。

验证不会运行sizeof()括号内任何代码

#include <stdio.h>

int main(int argc, char **argv)
{
  char c = 8;
  short s = 4;

  printf("sizeof(c): %ld\n", sizeof(c));
  // 结果是4,因为都转成int再运算,结果还是int类型
  printf("sizeof(c + 1): %ld\n", sizeof(c + 1));
  printf("sizeof(c + s): %ld\n", sizeof(c + s));
  printf("sizeof(c = c + s): %ld\n", sizeof(c = c + s));
  printf("sizeof(s = c + s): %ld\n", sizeof(s = c + s));
  printf("c: %d\n", c);
  printf("s: %d\n", s);

  return 0;
}

输出:

sizeof(c): 1
sizeof(c + 1): 4
sizeof(c + s): 4
sizeof(c = c + s): 1
sizeof(s = c + s): 2
c: 8
s: 4

#include <stdio.h>

int var = 0;

char add1(int a, int b)
{
  var = 1;
  printf("add1\n");
  return a + b;
}

short add2(int a, int b)
{
  var = 2;
  printf("add2\n");
  return a + b;
}

int add3(int a, int b)
{
  var = 3;
  printf("add3\n");
  return a + b;
}

long add4(int a, int b)
{
  var = 4;
  printf("add4\n");
  return a + b;
}

int main(int argc, char **argv)
{
  printf("var: %d\n", var);

  printf("add1: %ld\n", sizeof(add1));
  printf("add2: %ld\n", sizeof(add2));
  printf("add3: %ld\n", sizeof(add3));
  printf("add4: %ld\n", sizeof(add4));

  printf("========================\n");

  printf("add1(): %ld\n", sizeof(add1(1, 2)));
  printf("add2(): %ld\n", sizeof(add2(1, 2)));
  printf("add3(): %ld\n", sizeof(add3(1, 2)));
  printf("add4(): %ld\n", sizeof(add4(1, 2)));

  printf("var: %d\n", var);

  return 0;
}

输出:

var: 0
add1: 1
add2: 1
add3: 1
add4: 1
========================
add1(): 1
add2(): 2
add3(): 4
add4(): 8
var: 0

sizeof(整型)

#include <stdio.h>

int main(int argc, char **argv)
{
  // 整型
  short a;
  int b;
  long c;
  long long d;

  printf("short: %ld %ld\n", sizeof(a), sizeof(short));
  printf("int: %ld %ld\n", sizeof(b), sizeof(int));
  printf("long: %ld %ld\n", sizeof(c), sizeof(long));
  printf("long long: %ld %ld\n", sizeof(d), sizeof(long long));

  printf("===============================\n");

  unsigned short ua;
  unsigned int ub;
  unsigned long uc;
  unsigned long long ud;

  printf("unsigned short: %ld %ld\n", sizeof(ua), sizeof(unsigned short));
  printf("unsigned int: %ld %ld\n", sizeof(ub), sizeof(unsigned int));
  printf("unsigned long: %ld %ld\n", sizeof(uc), sizeof(unsigned long));
  printf("unsigned long long: %ld %ld\n", sizeof(ud), sizeof(unsigned long long));

  printf("===============================\n");

  printf("%ld == %ld\n", sizeof(short), sizeof(short int));
  printf("%ld == %ld\n", sizeof(long), sizeof(long int));
  printf("%ld == %ld\n", sizeof(long long), sizeof(long long int));

  return 0;
}

输出:

short: 2 2
int: 4 4
long: 8 8
long long: 8 8
===============================
unsigned short: 2 2
unsigned int: 4 4
unsigned long: 8 8
unsigned long long: 8 8
===============================
2 == 2
8 == 8
8 == 8

sizeof(字符型)

#include <stdio.h>

int main(int argc, char **argv)
{

  char c = 'a';

  printf("%ld\n", sizeof(c));
  printf("%ld\n", sizeof(char));

  // C结果:4,C++结果:1
  // C99的标准,    'a'是整型字符常量,常量!常量!常量!被看成是int型, 所以占4字节。
  // ISO C++的标准,'a'是字符字面量  ,被看成是char型,所以占1字节。
  printf("%ld\n", sizeof('a'));

  return 0;
}

输出:

1
1
4

sizeof(字符串型)

#include <stdio.h>

int main(int argc, char **argv)
{

  // 一个汉字3个字节,总共7个汉字,末尾加数字0,所以3*7+1=22
  char str[] = "老师,早上好!";
  char buf[50] = "老师,早上好!";
  char *p = "老师,早上好!";

  printf("%ld\n", sizeof(str));
  printf("%ld\n", sizeof(buf));
  printf("%ld\n", sizeof(p));
  printf("%ld\n", sizeof(*p));
  printf("%ld\n", sizeof("老师,早上好!"));

  return 0;
}

输出:

22
50
8
1
22

sizeof(结构体)

#include <stdio.h>

struct T1 {
  // pos = 0
  int a;
  // pos = 4
  char b;
  // pos = 8
  long c;
  // pos = 16
  short d;
  // pos = 18
  // 由于结构体的大小必须是机器字长(单位字节)的整数倍
  // 若x64,则机器字长8字节,结构体的大小必须是8的整数倍
  // 所以大小扩大到24
};

struct T2 {
  // pos = 0
  int a;
  // pos = 4
  char b;
  // pos = 8
  long c;
  // pos = 16
  short d;
  // pos = 18
  // 由于结构体的大小必须是机器字长(单位字节)的整数倍
  // 若x64,则机器字长8字节,结构体的大小必须是8的整数倍
  // 所以大小扩大到24

  // 验证剩余空间还有6字节
  char ch1;
  char ch2;
  char ch3;
  char ch4;
  char ch5;
  char ch6;
};

struct T3 {
  // 验证结构体的大小必须是机器字长(单位字节)的整数倍
  char a;
};

struct T4 {
  // 验证结构体的大小必须是机器字长(单位字节)的整数倍
  char a;
  short b;
};

struct T5 {
  // 验证结构体的大小必须是机器字长(单位字节)的整数倍
  char a;
  int b;
};

struct T6 {
  // 验证结构体的大小必须是机器字长(单位字节)的整数倍
  char a;
  long b;
};

int main(int argc, char **argv)
{

  printf("sizeof(struct T1): %ld\n", sizeof(struct T1));
  printf("sizeof(struct T2): %ld\n", sizeof(struct T2));
  printf("sizeof(struct T3): %ld\n", sizeof(struct T3));
  printf("sizeof(struct T4): %ld\n", sizeof(struct T4));
  printf("sizeof(struct T5): %ld\n", sizeof(struct T5));
  printf("sizeof(struct T6): %ld\n", sizeof(struct T6));

  return 0;
}

输出:

sizeof(struct T1): 24
sizeof(struct T2): 24
sizeof(struct T3): 1
sizeof(struct T4): 4
sizeof(struct T5): 8
sizeof(struct T6): 16