C语言笔记第十四天

好啦,最后一天了,C语言就结束了.之后在简单的说下Linux,然后就C++吧.

结构体强制类型对齐

#pragma pack(n) n为2的n次方

与默认选择对齐方式取最小值

其实实际上是牺牲时间换空间,这个是有用的.(结构体内类型的数据也会使结构体内存发生变化)

位段(位域)

只有unsigned int 和 unsiged char

struct BitField

{

占两位

unsigned int a:2;

占四位

unsigned char b:4;

}

相邻位域可以压缩成一块内存,不能超过自身字节数

位段不能取地址(因为步长(最小操作的是一个字节))

赋值不能越界(越界会截断)

占位位段

struct BitField

{

占两位

unsigned char a:2;

只占位

unsigned char :2; //当占位为0的时候会重新开辟字节

占四位

unsigned char c:4;

}

清空数据时可以memset

这个比左移右移方便多了,不过这个嵌入式范围,有兴趣的可以了解下,没兴趣无所谓(毕竟一般也不会真的需要对位进行操作)

共用体

union Data{

int a;

char b;

double c;

};

由最大的数据类型决定空间大小

同一时间只能使用一个

赋值的时候会覆盖(具体值是按照具体类型决定的)

其余操作和结构体相同

这个其实也是单片机的操作,这里也不细说了.

枚举

枚举的意义很大的,可以理解成他是升级版的宏(当然了,只是普通常量)

enum Data{NUM,NUM2,NUM3,NUM4};
如果不定义重0开始不断的加1(NUM = 0,NUM2 = 1,NUM3 = 2,NUM4 = 3)

如果赋值则是从赋值位置开始不断的加1
enum Data{NUM,NUM2 = 10,NUM3,NUM4};
NUM = 0,NUM2 = 10,NUM3 = 11,NUM4 = 12

也可以
enum Data{NUM = 54,NUM2 = 10,NUM3 = 23,NUM4 = 92};
#include <stdio.h>

enum MyEnum
{
	NUM = 10, NUM2 = 5, NUM3 = 54
};

int main()
{
	enum MyEnum n = NUM2;

	printf("%d\n", n);

	return 0;
}

下午把链表,文件读写搞定然后C语言就结束了

想了一下,回炉嘛那数据结构呢,链表还是等那时候再来吧.直接上文件读写吧.

文件读写

文件是读写到缓冲区然后再到硬盘,这样可以提高效率,也可以增加硬盘使用寿命.

文件实际上都是以二进制进行存储(字节为单位),分为字符编码文件(文本文件)和值编码文件(二进制文件)两种.

        字符编码文件(文本文件):通常以ASCII和Unicode解析(便于查看)

                空间利用率低(字节操作)

        值编码文件(二进制文件):二进制原样解析(不是人看的东西)

                空间利用率高(位操作)

三个特殊的文件指针

stdin 标准输入(终端键盘) stdout 标准输出(终端屏幕) stderr 标准错误(终端屏幕)

文件读写函数

fopen

参数一要打开文件的名字,参数二打开方式

打开失败返回NULL
打开方式: 图片来自网络

fclose

关闭文件,参数文件指针

文件结尾

文本文件结尾是EOF

二进制文件结尾使用feof函数判断

文件读写函数

字节读写:fgetc fputc

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>
#include <string.h>

int main()
{
	//定义文件指针
	FILE* fp = NULL;
	
	//以写的方式打开文件,文件不存在创建文件
	fp = fopen("./text.txt", "w");

	//判断文件打开是否成功
	if (fp == NULL)
	{
		perror("fopen");
		return 0;
	}

	//写入文件
	fputc('h', fp);
	fputc('e', fp);
	fputc('l', fp);
	fputc('l', fp);
	fputc('o', fp);

	//关闭文件
	fclose(fp);

	//读取文件
	//以读的方式打开文件
	fp = fopen("./text.txt", "r");
	if (fp == NULL)
	{
		perror("fopen");
		return 0;
	}

	char ch = 0;
	
	//文本文件判断文件结尾
	while ((ch = fgetc(fp)) != EOF)
	{
		printf("%c", ch);
	}
	printf("\n");

	fclose(fp);

	return 0;
}

字符串读写:fgets fputs

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>
#include <string.h>

int main()
{
	//定义文件指针
	FILE* fp = NULL;

	//以写的方式打开文件,文件不存在创建文件
	fp = fopen("./text.txt", "w");
	if (fp == NULL)
	{
		perror("fopen");
		return 0;
	}

	//写入文件
	fputs("坚持到无能为力\n", fp);
	fputs("拼搏到感动自己\n", fp);

	fclose(fp);

	fp = fopen("./text.txt", "r");
	if (fp == NULL)
	{
		perror("fopen");
		return 0;
	}

	//文本文件判断文件结尾 实际中不要忘记了fgets是可以读取换行符的
    //结束返回null
	char buf[1024] = "";
	while (fgets(buf,sizeof(buf),fp))
	{
		printf("%s", buf);
		memset(buf, 0, sizeof(buf));
	}

	//去掉换行符
	//buf[strlen(buf) - 1] = 0;

	fclose(fp);

	return 0;
}

数据块读写:fread fwrite

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>
#include <string.h>

typedef struct
{
	char m_name[64];
	int m_age;
	int m_socre;
}Student;

int main()
{
	Student student[5] = {
		{"小红",18,60},
		{"小灰",19,70},
		{"小黑",20,80},
		{"小蓝",21,90},
		{"小绿",22,100}
	};

	//定义文件指针
	FILE* fp = NULL;

	//以写的方式打开文件,文件不存在创建文件
	fp = fopen("./text.txt", "w");
	if (fp == NULL)
	{
		perror("fopen");
		return 0;
	}

	//默认以二进制形式存储(内存原样输出到文件)
	//第一个参数数据首地址,第二个一次读取多大(字节),第三个读取几块,第四个文件指针
	fwrite(student, sizeof(student[0]), 5, fp);

	fclose(fp);

	fp = fopen("./text.txt", "r");
	if (fp == NULL)
	{
		perror("fopen");
		return 0;
	}

	//读文件
	Student student2[5] = { 0 };

	fread(student2, sizeof(student2[0]), 5, fp);

	for (int i = 0; i < 5; ++i)
	{
		printf("姓名:%s 年龄:%d 分数:%d\n", student2[i].m_name, student2[i].m_age, student2[i].m_socre);
	}

	fclose(fp);

	return 0;
}

格式化读写:fscanf fprintf

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>

typedef struct 
{
	char m_name[64];
	int m_age;
	int m_score;
}Student;

int main(int argc, char** argv)
{
	FILE* fp = fopen("text.txt", "w");
	if (fp == NULL)
	{
		perror("fopen");
		return 0;
	}

	Student s[5] = { 
		{"小红",18,60},
		{"小绿",19,70},
		{"小蓝",20,80},
		{"小份",21,90},
		{"小黑",22,100}
	};

	//写文件
	for (int i = 0; i < 5; ++i)
	{
		fprintf(fp, "姓名:%s 年龄:%d 分数:%d\n", s[i].m_name, s[i].m_age, s[i].m_score);
	}

	fclose(fp);

	fp = fopen("text.txt", "r");
	if (fp == NULL)
	{
		perror("fopen");
		return 0;
	}

	Student s2[5] = { 0 };

	//读文件
	for (int i = 0; i < 5; ++i)
	{
		fscanf(fp, "姓名:%s 年龄:%d 分数:%d\n", s2[i].m_name, &s2[i].m_age, &s2[i].m_score);
	}

	for (int i = 0; i < 5; ++i)
	{
		printf("姓名:%s 年龄:%d 分数:%d\n", s[i].m_name, s[i].m_age, s[i].m_score);
	}

	fclose(fp);

	return 0;
}

 文件定位函数

rewind

rewind(fp);

参数文件指针,

使流指针移动到文件首

ftell

ftell(fp);

参数文件指针,

获得距文件首的字节数,失败返回-1,返回值long

fseek

int fseek(fp,0,SEEK_SET); //将文件流指针移动到文件首

参数文件指针,偏移量,起始位置

起始位置

文件开头 SEEK_SET 0

文件当前位置 SEEK_CUR 1

文件末尾 SEEK_END 2

移动文件流指针到任意位置,成功时返回0,失败时返回非零,返回值int

feof

文件未结束返回0

while(!feof(fp))

{

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值