结构体 枚举 typedef
对结构体内存清零:
#include <stdio.h>#include <string.h>struct STU{int id;char sex;};int main(){struct STU s1;memset(&s1 , 0 , sizeof(s1));}

结构体内存对齐:
以结构体最长的类型对齐
#include <stdio.h>#include <string.h>struct STU{char sex;int id;};int main(){struct STU s1;memset(&s1, 0, sizeof(s1)); //把结构体内存清零s1.id = 0x12345678;s1.sex = 0x88;}
此结构体 sizeof = 8 内存如下:

struct STU{int id;// 4字节对齐char name[10];};
sizeof = 16
struct STU{char id; //最长字节就是char 1个字节char name[10];};
sizeof = 11
struct STU{short id;char name[10];};
sizeof = 12
struct STU{char * id; // 4char name[10]; // 12 4字节对齐};
sizeof = 16
struct STU{char id : 2; // 代表 id 是两个 bit 长};
sizeof = 1
结构体里的类型可以 bit 位 存储
#include <stdio.h>#include <string.h>struct STU{char id : 2; //两个bit位 如果存4的话就会是0 如果存5的话就会是1};int main(){struct STU s1;s1.id = 4;printf("%d\n" , s1.id);}

对齐只针对字节,不会针对位来对齐
struct STU{char id : 2;char name : 2;};
sizeof = 1
struct STU{int id : 2;};
sizeof = 4
struct STU{int id : 2;int age : 2;};
sizeof = 4
结构体之前的嵌套:
#include <stdio.h>#include <string.h>struct A{int i;char c;};struct B{int i;struct A a;};int main(){printf("%d\n" , sizeof(struct B));}
sizeof = 12
结构体之间的赋值:
结构体之间的赋值 原理就是内存的拷贝。
#include <stdio.h>#include <string.h>struct STU{char name[1024];};int main(){struct STU s1 = { "liuwei" };struct STU s2;s2 = s1; // memcpy( &s2 , &s1 , sizeof(s1)); 和这句话效果一样printf("%s\n",s2.name);}
结构体中 有指针的赋值:
如果是常量字符串,改变一个结构体的值,不会影响另外一个,因为内存中的地址不一样
#include <stdio.h>#include <string.h>struct STU{char *name;};int main(){struct STU s1 = { "liuwei" };struct STU s2;s2 = s1;s1.name = "xuanyuan";printf("%s\n",s2.name);}
但如果是在堆上开辟的新内存,那么复制的只是那个地址,指向的是同一块内存。如果改变了一个值,另外一个也会改变。
#include <stdio.h>#include <string.h>#include <stdlib.h>struct STU{char *name;};int main(){struct STU s1 , s2;s1.name = malloc(10);strcpy(s1.name , "liuwei");s2 = s1;strcpy(s1.name , "xuanyuan");printf("%s\n",s2.name);free(s1.name);}

函数体返回结构体,然后赋值其实是内存拷贝 注意这个大坑
#include <stdio.h>#include <string.h>struct str{char buf[1024];};struct str get_str(){struct str s;strcpy( s.buf , "hello world");return s;}int main(){struct str tmp = get_str(); //返回的是一个结构体变量,结构体变量之间的赋值,是内存拷贝printf("%s\n" , tmp.buf);return 0;}

注意其他类型变量与结构体之间的区别
#include <stdio.h>#include <string.h>char *get_str(){char buf[100];strcpy( buf , "hello world" );return buf;}int main(){printf("%s\n" , get_str() ); //输出乱码,因为buf的地址已经被函数释放了return 0;}

在退出get_str函数的时候,内存释放,输出乱码。

如果函数实在要返回结构体,就返回结构体指针把
#include <stdio.h>#include <string.h>#include <stdlib.h>struct str{char buf[1024];};struct str *get_str(){struct str *s = malloc(sizeof( struct str ));strcpy( s->buf , "hello world");return s;}int main(){struct str *tmp = get_str();printf("%s\n" , tmp->buf);free(tmp);return 0;}
返回结构体指针的一种错误方法
#include <stdio.h>#include <string.h>struct str{char buf[1024];};struct str *get_str(){struct str s;strcpy( s.buf , "hello world");return &s; //虽然返回的是结构体的地址,但是结构体的内存是在栈上,函数结束被释放}int main(){struct str *tmp = get_str();printf("%s\n" , tmp->buf);return 0;}
枚举的生长规律 是根据前一个值 再+1
#include <stdio.h>int main(){enum color{ red = 11 , yellow = 10 , blue};printf("%d\n",blue);return 0;}
需要注意的是枚举里面是以逗号分隔的,而不是以分号。
typedef的威力:
#include <stdio.h>#include <string.h>#include <stdlib.h>//这个函数是连接两个字符串const char *func( const char *str1 , const char *str2 ){char *p = malloc( strlen(str1) + strlen(str2) + 1 );strcpy( p , str1);strcat( p , str2);return p;}//如果要定义这个函数的 函数指针 如下const char *(*p)( const char *str1 , const char *str2 );int main(){p = func;char * s = p("hello","world");printf("%s\n",s);return 0;}
但是这样的函数指针看上去是不是很蛋疼呢?
typedef const char *(*FUNC)( const char *str1 , const char *str2 );
可以用typedef 定义这个 函数指针 类型
方便以后使用

浙公网安备 33010602011771号