1昨日回顾

2作业讲解

3 结构体的基本定义

//1

struct teacher

{

int id;

char name[64];

};

struct teacher t5 = { 5, "laoshi5" };

//2

struct {

int id;

char name[64];

} t3, t4;//匿名的结构体类型  类型只能定义一次, 不能通过函数传参

//3

typedef struct  _teacher

{

int id;

char name[64];

} teacher_t;  //最常用的写法

/*

struct _teacher

{

int id;

char name[64];

};

typedef struct _teacher teacher_t;

*/

void print_teacher(struct teacher* p1)

{

printf("id = %d\n", p1->id);

printf("name = %s\n", p1->name);

}

void print_teacher2(struct teacher t) //t = t1     int a = b; struct teacher t1 = t2

{

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

printf("id = %d\n", t.id);

printf("name = %d\n", t.name);

}

void copy(struct teacher to, struct teacher from)

{

to = from;

}

void copy2(struct teacher *to, struct teacher *from)

{

*to = *from;

}

/*

void print_teacher2(struct {

int id;

char name[64];

})

*/

int main(void)

{

struct teacher  t1;

struct teacher  t8;

teacher_t t6 = {6, "laoshi6"};

//teacher t7;  // C语言中  定义一个结构体 必须加上struct 关键字  C++不用加

t1.id = 10;

strcpy(t1.name, "laoshi1");

print_teacher(&t1);

print_teacher(&t5);

print_teacher2(t1);  //

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

copy2(&t8, &t1);

print_teacher(&t8);

struct teacher t9 = t1; //int a = b;

return 0;

}

4 结构体作为函数参数

5结构体嵌套一级指针

#define  _CRT_SECURE_NO_WARNINGS

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#define NAME_LEN (64)

struct teacher

{

int id;

char *name;

};

int create_teachers(struct teacher **tpp, int num)

{

if (tpp == NULL) return;

struct teacher *tp;

int i = 0;

// 在堆上分配空间

tp = (struct teacher*) malloc(sizeof(struct teacher)* num);

if (tp == NULL)

{

fprintf(stderr, "malloc tp error\n");

return -1;

}

memset(tp, 0, sizeof(struct teacher) * num);

for (i = 0; i < num; i++)

{

// 在堆上给name分配空间

tp[i].name = (char *)malloc(sizeof(char)*NAME_LEN);

memset(tp[i].name, 0, sizeof(char)*NAME_LEN);

}

// 开辟完之后把指针传出去

*tpp = tp;

return 0;

}

void sort_teacher(struct teacher *tp,int num)

{

int i = 0;

int j = 0;

struct teacher temp_teacher;

for (i = 0;i<num-1;i++)

{

for (j = i; j < num; j++)

{

// 每次把最小的放到数组最开始的位置

if (tp[i].id > tp[j].id) {

temp_teacher = tp[i];

tp[i] = tp[j];

tp[j] = temp_teacher;

}

}

}

}

void print_teacher(struct teacher* p, int num)

{

int i = 0;

for (i = 0; i < num; i++)

{

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

printf("id:%d\n", p[i].id);

printf("name:%s\n", p[i].name);

}

}

// 内存释放

void free_teachers(struct teacher **tpp,int num)

{

if (tpp == NULL)

{

return;

}

struct teacher *tp = *tpp;

int i = 0;

if (tp != NULL)

{

for (i = 0; i < num; i++) {

if (tp[i].name != NULL)

{

free(tp[i].name);

tp[i].name = NULL;

}

}

free(tp);

*tpp = NULL;

printf("free success\n");

}

}

int main(int argc,char* argv[])

{

// 创建两个老师

// 创建结构体指针

struct teacher *tp = NULL;

int num = 2;

int i = 0;

int ret = 0;

// 传入指针,通过二级指针接收来对此指针所指向内存区域进行修改

ret = create_teachers(&tp, num);

if (ret < 0) return -1;

// 为堆上的name的位置赋值

for (i = 0; i < num; i++)

{

printf("enter tp[%d]'s id :", i);

scanf("%d", &tp[i].id);

printf("enter tp[%d]'s name :", i);

scanf("%s", tp[i].name);

}

print_teacher(tp, num);

sort_teacher(tp, num);

print_teacher(tp, num);

free_teachers(&tp, num);

return 0;

}

6结构体深拷贝和浅拷贝问题

// 结构体可以通过变量直接赋值,但不要使用这种方法

// 要给结构体中的成员 一个一个的拷贝

如果结构体中有指针,浅拷贝后可能会造成重复释放的问题

7结构体内部成员的偏移量

偏移:

8中午回顾

9结构体嵌套二级指针开辟内存空间

10结构体嵌套二级指针释放空间

11结构体字节对齐

举个例子:

1

2

3

4

5

6

struct {

char a;    //1byte

int b;    //4byte

char c[2]    //2byte

double d;    //8byte

}Struct_A;

在计算机内存中,结构体变量的存储通常是按字长对齐的,比如8位机里就按字节对齐,那么上述结构体共占用1+4+2+8=15byte。

在16位机里,变量就按照2字节对齐,比如a这个成员,虽然是个char类型,地址在0x80000000本身只占1字节,但是下一个成员b却不能使用0x80000001这个地址,而必须使用0x80000002,这就是按字长对齐。以上结构体占用的空间也就是2+4+2+8=16字节

同理,在32位机中,如果a在0x80000000的话,b只能放在0x80000004,因为这里的字长是4个字节。以上结构体占用空间4+4+4+8=20字节

也就是说总有一些字节是浪费掉的,这样做的目的很简单,就是因为在大多数计算机体系结构中,对内存操作时按整字存取才能达到最高效率,相当于是以空间换取时间。当然在某些计算机体系结构中,比如ARM,是支持非对齐字传输的,也就是说变量并不一定要按照字长对齐,尽管这样可能会降低效率,但换来的是存储空间上的节约。对于程序员来讲,则需要将结构体声明为紧凑型结构体。声明的关键字依编译器不同而异,你可以去查一下__packed关键字,可以得到更详细的说明。使用紧凑型结构体,则会强制编译器将结构体成员按1字节对齐,则以上结构体占用空间仍为15字节。

资料:

https://bbs.csdn.net/topics/392057821

12不完整类型字节序对齐

13位移操作符

14掩码

~按位取反运算符

题目:从八位开始找四位。。。这个函数实现

0按位取反编程全1 然后向左偏移n位 然后再全部取反 与 源数据x向右偏移position位 相与

?

9.文件的操作

mysql oracle 存到硬盘中的数据库

redis mongodb 内存型数据库

(缓冲区满了以后刷新缓冲区,存到文件中

cpu在不同进程间不停切换 ,如果没有缓冲区 cpu直接把100k放到磁盘中,然后切换进程2 然后切换进程1

现在有了缓冲区,cpu可以先把100k放到内存中(很快),然后就可以去切换进程2,后面让内存与磁盘进行交互io 效率提升

文件结构体:

操作系统通过限制文件描述符fd的数目来限制打开文件的个数

standard C I/O

fputc:

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

#define FILE_NAME "C:/Users/lg/Desktop/1.txt"

// 字符的写操作

void test_write_char()

{

char *buf = "abcdefghij";

int i = 0;

FILE *fp = fopen(FILE_NAME, "w+");

if (fp == NULL) {

fprintf(stderr, "open %s error \n", FILE_NAME);

return -1;

}

for (i = 0; i < (int)strlen(buf); i++)

{

if (fputc(buf[i], fp) == EOF) {

fprintf(stderr, "fput %c error\n", buf[i]);

break;

}

}

if (fp != NULL)

{

fclose(fp);

}

return 0;

}

int test_read_char()

{

FILE *fp = NULL;

char buf[128] = { 0 };

char ch = 0;

int i = 0;

fp = fopen(FILE_NAME, "r+");

if (fp == NULL)

{

fprintf(stderr, "fopen %s error\n",FILE_NAME);

}

while ( (ch = fgetc(fp)) != EOF)

{

buf[i] = ch;

i++;

}

printf("buf:%s\n",buf);

if (fp != NULL)

{

fclose(fp);

}

return 0;

}

int main(void)

{

test_write_char();

test_read_char();

return 0;

}

fputs fgets: 操作str

fputs不会把’\n’写进去

注意:1.fputs不会把字符串的\0写进去

2.fputs不会写\n

注意:fgets不是根据\0来从文件区分一行,而是通过\n,并会把\n读进去

总结一下:

int fputc(ch,fp)  (返回值是字符ascii码)

int fgetc(fp)       (返回值是字符ascii 码)

int fputs(buf,fp)

char * fgets(buf,len,fp)

文件的随机存取操作

ftell

fseek

配置文件的测试框架

多文件形式编程

配置文件的写配置实现

C语言提高 (5) 第五天 结构体,结构体对齐 文件的更多相关文章

  1. C语言第五次作业——循环结构

    C语言程序设计第五次作业--循环结构(1) (一)改错题 输出华氏摄氏温度转换表:输入两个整数lower和upper,输出一张华氏摄氏温度转换表,华氏温度的取值范围是{lower,upper},每次增 ...

  2. C语言之结构体内存的对齐

    C语言之结构体内存的对齐 大纲: 零.引例 一.结构体内存对齐规则 二.怎样计算结构体的大小 三.设计结构体时要注意的方面   四.为什么存在内存对齐 五.修改默认对齐数 在前面的章节中,我们谈到了C ...

  3. GO语言的进阶之路-go的程序结构以及包简介

    GO语言的进阶之路-go的程序结构以及包简介 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.编辑,编译和运行 A,编辑 Go程序使用UTF-8编码的纯Unicode文本编写.大 ...

  4. C语言结构体的内存对齐问题

    在C语言开发当中会遇到这样的情况: #include <stdio.h> struct test { int a; char b; }; int main(int argc, const ...

  5. C语言实现GBK/GB2312/五大码之间的转换(转)

    源:C语言实现GBK/GB2312/五大码之间的转换 //----------------------------------------------------------------------- ...

  6. C语言高级-结构,共用体,文件,链表

    C语言结构 标准声明方式 struct student{        int age;        char sex;    }; 这个可以在main函数中定义:  struct student ...

  7. C语言结构体的字节对齐原则

    为什么要对齐? 现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定类型变量的时候经常在特 定的内存地址访问,这就需要各种类型数据 ...

  8. C语言高速入门系列(五)

    C语言高速入门系列(五) C语言指针初涉                                           ------转载请注明出处:coder-pig 本节引言: 上一节我们对C ...

  9. C语言实现使用动态数组来构造栈结构

    我在面前一篇博客<C语言实现使用静态数组来构造栈结构>中使用了静态数组来模拟栈的操作.静态数组的大小是在代码中写死的.是存储在用户栈上面的,使用起来不灵活.在这篇博客中我会使用动态数组来构 ...

随机推荐

  1. DJANGO之自定义模板过滤器

    我查找了DJANGO模板的过滤器,好像指定字符串包含指定关-键字符的过滤器没有呢, 没有硬着头-皮,按网上其它人的作法,写了一个,成功了...:) 参考URL: http://liuzhijun.it ...

  2. ios自己定义类(UIView)代码生成简单的UITableViewCell

    因为一个项目中有大量的UITableViewCell须要书写,样式几乎相同都是 文字介绍:显示内容 这种. 自己又懒得写UITableViewCell类嫌不是必需:在方法tableView:cellF ...

  3. 新手git: ssh: connect to host localhost port 22: Connection refused

    由于gitlab上要git pull或者git clone,可是每次都出现这个问题.之前偶尔出现这个问题.可是仅仅是偶尔.这是为什么呢?然后就開始搜索网上的解决方式了. 这个问题搜索网上非常多答案.可 ...

  4. SICP 习题1.16-1.19体会

    首先反思一下, 昨天做1.14的时候犯了一个严重错误.思维定式了,导致花了非常多无用功. 1.14的关键是要想到2个物理意义. 一个是广度优先, 也就是仅仅考虑问题递归树的第一层子数.那么必定有公式 ...

  5. Android 四大组件学习之ContentProvider二

    上节学习了什么是ContentProvider.以及ContentProvider的作用.以及什么是URL.本节就对上节学习的知识做一个实践,也就是定义自己的ContentProvider 好.实践是 ...

  6. luogu2761 软件补丁问题 状态压缩最短路径

    关键词:状态压缩 最短路径 想不出快速办法,就先考虑考虑暴力.枚举每一种错误分布的情况,然后通过可用的补丁转化为另多种情况,这些情况又转化为更多种情况……我们可以用图来表示这种关系! 状态压缩:每个错 ...

  7. hdoj--1151--Air Raid(最大独立集)

    Air Raid Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S ...

  8. hdoj--2509--Be the Winner(尼姆博弈)

    Be the Winner Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) To ...

  9. [IOI 2008] Island

    [题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=1791 [算法] 不难看出,要求的是这个基环树森林中每棵基环树的直径之和 [代码] # ...

  10. vue项目中阻止浏览器返回上一页

    vue项目中在某个页面阻止浏览器返回上一页,适用移动端.PC端. 使用场景例如: 首页 与 A页面     来回跳转,那样点击浏览器返回时也会来回跳转,本想当页面在首页的时候就不再返回了,所以这个时候 ...