1.1 宏定义
例题1
typedef struct student
{
int a;
char b[20];
double c;
}Stu;
#define FIND(Stu, b) ((unsigned int)&(((Stu*)0)->b))
{
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;
}
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;
}
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;
}
#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;
}
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;
}
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;
}
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;
}
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;
}
float a;
char p;
int c[3];
};
int main() {
printf("sizeof(struct A): %d\n", sizeof(struct A));
return 0;
}
输出结果如下图所示: