#include <stdio.h> #include <string.h>
struct peple { char name[20]; int age; }; struct student { int s1; char s2; double s3; }s; int main() { struct peple zhangsan; strcpy(zhangsan.name,"张三"); //结构体中的数组要使用strcpy进行赋值;
zhangsan.age = 19; printf("%s,.%d\n",zhangsan.name,zhangsan.age);
// 结构体 . 访问和 -> 访问,实质上都是指针访问呢,只是编译器对此做了优化; // 下面是对 . 访问的 指针式理解
s.s1 = 4; // int *p1 = (int *)&s; *p1 = 4;
s.s2 = 'e'; // char *p2 = (char *)((int)&s + 4); *p2 = 'e';
s.s3 = 3.3; // double *p3 = (double *)((int)&s + 8); *p3 = 3.3;
printf("%d, %c, %f\n",s.s1,s.s2,s.s3); int *p1 = (int *)&s; char *p2 = (char *)((int)&s + 4); double *p3 = (double *)((int)&s + 8); //这里是 +8, 而不是 +5
printf("%d, %c, %f\n",*p1,*p2,*p3); return 0; }
#include <stdio.h> typedef struct E { // 共占24字节 共占9字节 共占20字节 共占24字节 共占24字节
short i; // 2 2 2 2
short j; // 2 2 2 2
char m; // 1(1+3) 1 1(1+1) 1(1+3)
int n; // 4 4 4 4
struct A a; // 12 9 10 12
}E; #pragma pack() typedef struct { // 共占9字节
short i; // 2
short j; // 2
char m; // 1
int n; // 4
}__attribute__((packed)) CC; // 1字节对齐 2字节对齐 4字节对齐 8字节对齐
struct mystruct111 { // 共占12字节 共占12字节 共占12字节 共占16字节
int a; // 4 4 4 4
char b; // 1 1 1 1
short c; // 2 2 2 2
short d; // 2 2 2 2
}__attribute__((aligned(8))) My111;
#include <stdio.h>
// TYPE是结构体类型,MEMBER是结构体中一个元素的元素名 // 这个宏返回的是member元素相对于整个结构体变量的首地址的偏移量,类型是int
#define offsetof(TYPE, MEMBER) (int)(&((TYPE *)0) -> MEMBER )
// ptr是指向结构体元素member的指针,type是结构体类型,member是结构体中一个元素的元素名 // 这个宏返回的就是指向整个结构体变量的指针,类型是(type *)
#define container_of(ptr, type, member) ({ \
const typeof(((type *)0)->member) * __mptr = (ptr); \ (type *)((char *)__mptr - offsetof(type, member)); }) struct cc { char a; short b; int c; }; int main(void) { struct cc s; s.b = 12; struct cc *pS = NULL; short *p = &(s.c); pS = container_of(p, struct cc, c); printf("&s.a = %p\n", &s); //&s.a = 0xbfd88d44
printf("&s.c = %p\n", p); //&s.c = 0xbfd88d48
printf("&pS = %p\n",pS); //&pS = 0xbfd88d44
printf("&s.b = %p\n", &(s.b)); //&s.b = 0xbfd88d46
printf("&s.b = %p\n", &(pS->b)); //&s.b = 0xbfd88d48
printf("pS.b = %d\n", pS->b); //12
return 0; }
#include <stdio.h> union myunion { int a; float b; char c; double d; }; struct aa { char i; int j; double d; }a1; int main(void) { union myunion t1; t1.a = 1123477881; printf("value = %f.\n", t1.b); //123.456001
int a = 1123477881; printf("指针方式:%f.\n", *((float *)&a)); //123.456001
t1.a = 12; printf("s1.b = %d.\n", t1.b); printf("s1 = %d\n", sizeof(union myunion)); //8
printf("a1 = %d\n", sizeof(struct aa)); //16
return 0; }
#include <stdio.h> union endian //共用体都是从地地址开始访问的
{ char i; int j; }s; //小端模式返回1,不然为大端模式
int is_little_endian1(void) { s.j = 1; // 地址0的那个字节内是1(小端)或者0(大端)
return s.i; } int is_little_endian2(void) { int i = 1; char p = *((char *)(&i)); return p; } int main(void) { char i; // i = is_little_endian2(); //union测试
i = is_little_endian2(); //指针测试
if(i == 1) { printf("小端模式\n"); } else { printf("大端模式\n"); } return 0; }
#include <stdio.h>
//这个枚举用来表示函数返回值,error表示错误,right表示正确
enum return_value { error = 12, //枚举值是全局的,直接本身就能够用;
right , //由于枚举是全局的,因此全部的枚举类型中,常量符号都不能相同
}; enum return_value func1(void) { enum return_value r1 = right; return (r1); } int main(void) { printf("error = %d\n", error); printf("right = %d\n", right); enum return_value s = func1(); if(s == error) { printf("函数执行错误\n"); } else { printf("函数执行正确\n"); } return 0; }