第六章 预处理、const、sizeof

1.1 宏定义

例题1

typedef struct  student 
{
int a;
char b[20];
double c;
}Stu;


#define FIND(Stu, b)  ((unsigned int)&(((Stu*)0)->b))


例题2 

#define SECONDS_OF_YEAR (365*24*3600)UL


int main(){
printf("sizeof(int) = %d, sizeof(short int) = %d, sizeof(long int) = %d\n", \
sizeof(int), sizeof(short int), sizeof(long int));
return 0;
}




例题3: MIN宏实现

#define MIN(X, Y)  ((X) < (Y)) ? (X):(Y)
int main(){
int x = 0, y = 0, z = 0;
scanf("%d%d", &x, &y);
z= MIN(x, y);
printf("z = %d\n", z);
printf("MIN(x, y) = %d\n", MIN(x, y));
return 0;
}


输入如下图所示:


1.2 sizeof

例题1:

#include "stdlib.h"
#include <string.h>
struct {
short a1;
short a2;
short a3;
}A;


struct {
long a1;
short a2;
}B;


int main() {
char *ss1 = "0123456789";
char ss2[] = "0123456789";
char ss3[100] = "0123456789";
int ss4[100];
char q1[] = "abc";
char q2[] = "a\n";
char* q3="a\n";
char *str1 = (char*)malloc(100);
str1[99] = '\0';
void *str2 = (void*)malloc(100);
printf("sizeof(ss1): %d\n", sizeof(ss1)); 
printf("strlen(ss1): %d\n\n", strlen(ss1));
printf("sizeof(ss2): %d\n", sizeof(ss2)); 
printf("strlen(ss2): %d\n\n", strlen(ss2));
printf("sizeof(ss3): %d\n", sizeof(ss3));
printf("strlen(ss3): %d\n\n", strlen(ss3));
printf("sizeof(ss4): %d\n\n", sizeof(ss4));
printf("sizeof(q1): %d\n", sizeof(q1));
printf("strlen(q1): %d\n\n", strlen(q1));
printf("sizeof(q2): %d\n", sizeof(q2));
printf("strlen(q2): %d\n\n", strlen(q2));
printf("sizeof(q3): %d\n", sizeof(q3));
printf("strlen(q3): %d\n\n", strlen(q3));
printf("sizeof(A): %d\n\n", sizeof(A));
printf("sizeof(B): %d\n\n", sizeof(B));
printf("sizeof(str1): %d\n", sizeof(str1));
printf("strlen(str1): %d\n\n", strlen(str1));
printf("sizeof(str2): %d\n", sizeof(str2));
printf("strlen(str2): %d\n\n", strlen((char*)str2));
return 0;
}


上图输出结构如下图所示:

//P48 主要考查sizeof与strlen的区别;结构体的对齐方式。
sizeof计算中的分配的大小;strlen计算字符串的大小,是个函数实现,不包括结束符号‘\0’。
结构体的对齐规则:
1. 结构的成员按自己的对齐方式(如int为4字节,char为1字节等)与Pack(n)指定的最小值来对齐(结构体成员小于处理器的位数)。
2. 当结构体的成员大于处理器的位数时,结构的成员按处理器的位数来对齐。
3. 对齐后的总长度必须是结构体的成员中最大的对齐参数的整数倍。
如A结构体:
A.a1自身对齐为short 2个字节,占0x00000000-0x00000001的空间,且0x00000000%2=0;A.a2自身对齐为short 2个字节,占0x00000002-0x00000003的空间,且0x00000002%2=0;A.a3自身对齐为short 2个字节,占0x00000004-0x00000005的空间,且0x00000004%2=0;
那对齐后的长度为6个字节,这时结构体成员中最大的对齐参数为2个字节,6/2 = 0, 所以最终占了6个字节。
如B结构体:
B.a1自身对齐为long 4个字节,占0x00000000-0x00000003的空间,且0x00000000%2=0;B.a2自身对齐为short 2个字节,占0x00000004-0x00000005的空间,且0x00000004%2=0;
那对齐后的长度为6个字节,这时结构体成员中最大的对齐参数为4个字节,(6+2)/4 = 0, 所以填充2个字节的0,最终占了8个字节。

例题2

struct B {
bool m_bTemp;
int m_nTemp;
bool m_bTemp2;


};


struct C {
int m_bTemp;
bool m_nTemp;
bool m_bTemp2;
};


int main() {
printf("sizeof(B): %d\n", sizeof(B));
printf("sizeof(C): %d\n", sizeof(C));
return 0;
}



输出结果如下:详细请参照上面的对齐规则。


例题3

struct A {
int a;
static int b;
};


struct B {
int a;
char b;
};


struct C {
float a;
char b;
};


struct D {
float a;
int b;
char c;
};


struct E {
double a;
float b;
int c;
char d;
};


int main() {
struct E Fa;
printf("sizeof(A): %d\n", sizeof(A));
printf("sizeof(B): %d\n", sizeof(B));
printf("sizeof(C): %d\n", sizeof(C));
printf("sizeof(D): %d\n", sizeof(D));
printf("sizeof(E): %d\n", sizeof(E));
printf("%p,%p, %p, %p", &Fa.a, &Fa.b, &Fa.c, &Fa.d);
return 0;
}


输出结果如下图所示:
结合对齐规则,好好理解struct E。


例题4

int main() {
int **a[3][4];
printf("sizeof(**a[3][4]): %d", sizeof(a));
return 0;
}


输出所下图所示:指针固定占4个字节


例题5

int test(char var[]) {
return sizeof(var);
}
int main() {
char var[10];
int i = 0;
i = test(var);
printf("sizeof(var): %d", i);
return 0;
}


函数调用退化为指针


例题6

struct A {
float a;
char p;
int c[3];
};


int main() {
printf("sizeof(struct A): %d\n", sizeof(struct A));
return 0;
}


输出结果如下图所示:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值