Cday03---calloc和realloc

1. calloc和realloc

在这里插入图片描述

void test()
{
	int* p = calloc(10, sizeof(int));
	for (int i = 0; i < 10; ++i)
		p[i] = i + 1;
	for (int i = 0; i < 10; ++i)
		printf("%d ", p[i]);

	if (p != NULL)
	{
		free(p);
		p = NULL;
	}
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

void test()
{
	int* p = malloc(sizeof(int) * 10);
	for (int i = 0; i < 10; ++i)
		p[i] = i + 1;
	for (int i = 0; i < 10; ++i)
		printf("%d ", p[i]);
	printf("\n%d\n", p);
	p = realloc(p, sizeof(int) * 20);
	printf("%d\n", p);
	for (int i = 0; i < 10; ++i)
		printf("%d ", p[i]);
	if (p != NULL)
	{
		free(p);
		p = NULL;
	}
}

在这里插入图片描述

2. sscanf

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

void test()
{
	//%*s或%*d  忽略数字或字母,跳过数据
	char* str = "12345abcde";
	char buf[1024] = { 0 };

	sscanf(str, "%*d%s", buf);
	printf("buf: %s\n", buf);
}

在这里插入图片描述

void test()
{
	//%*s或%*d  忽略数字或字母,跳过数据
	//忽略字符串到空格或者\t
	char* str = "abcde 12345";
	char buf[1024] = { 0 };
	sscanf(str, "%*s%s", buf);
	printf("buf: %s\n", buf);
}

在这里插入图片描述

void test()
{
	//%[width]s  读指定宽度的数据
	char* str = "12345abcde";
	char buf[1024] = { 0 };
	sscanf(str, "%6s", buf);
	printf("buf: %s\n", buf);
}

在这里插入图片描述

void test()
{
	//任何匹配从第一个字符开始,如果不满足条件会直接退出匹配过程
	//%[a - z]  匹配a到z中任意字符
	char* str = "12345abcde";
	char buf[1024] = { 0 };
	sscanf(str, "%*d%[a-c]", buf);//先忽略数字
	printf("buf: %s\n", buf);
}

在这里插入图片描述

void test()
{
	//%[aAb]   匹配aAb中的一员,贪婪性
	char* str = "aABbcde";
	char buf[1024] = { 0 };
	sscanf(str, "%[aAb]", buf);
	printf("buf: %s\n", buf);
}

在这里插入图片描述

void test()
{
	//%[^a]   匹配非c的任意字符,贪婪性
	char* str = "aABbcde";
	char buf[1024] = { 0 };
	sscanf(str, "%[^c]", buf);
	printf("buf: %s\n", buf);
}

在这里插入图片描述

void test()
{
	//%[^a-z]   表示读取除a-z以外的所有字符
	char* str = "1234aABbcde";
	char buf[1024] = { 0 };
	sscanf(str, "%[^a-z]", buf);
	printf("buf: %s\n", buf);
}

在这里插入图片描述

void test()
{
	char* str = "abcde#12uiop@0p1";
	char buf[1024] = { 0 };
	sscanf(str, "%*[^#]#%[^@]", buf);
	printf("buf: %s\n", buf);
}

在这里插入图片描述

3. 查找子串

在这里插入图片描述

//查找子串第一次出现的位置
char* myStr(const char* str, const char* substr)
{
	const char* mystr = str;
	const char* mysub = substr;

	while (mystr != '\0')
	{
		if (*mystr != *mysub)
		{
			++mystr;
			continue;
		}
		//此时已找到第一个相同的字母
		const char* temp_mystr = mystr;
		const char* temp_mysub = mysub;
		while (*temp_mysub != '\0')
		{
			if (*temp_mystr != *temp_mysub)
			{
				++mystr;
				break;
			}
			++temp_mysub;
			++temp_mystr;
		}
		if (*temp_mysub == '\0')
			return (char*)mystr;
	}
	return NULL;
}

void test()
{
	char* str = "abcdefg";
	char* sub = "de";
	char* pos = myStr(str, sub);
	printf("pos = %s\n", pos);
}

在这里插入图片描述

4. 指针易错点

4.1 越界
在这里插入图片描述
4.2 指针叠加会不断改变指针指向,所以最后无法free§
在这里插入图片描述
4.3 返回局部变量地址。当操作某块内存时,该内存需要是合法的(自己申请,使用的时候还没释放)
在这里插入图片描述
4.4 同一内存释放多次

void test()
{
	char* p = NULL;
	p = (char*)malloc(50);
	strcpy(p, "abcdef");
	if (p != NULL)
	{
		//free()函数的功能只是告诉系统p指向的内存可以回收了,即将p
		//指向的内存使用权交还给系统,但是p的值还是原来的值(野指针),
		//p还是指向原来的内存
		free(p);
	}
}

5. const的使用

在这里插入图片描述

struct Person
{
	char name[64];
	int age;
	int ID;
	double score;
};

//使用值传递,每次开辟80字节的空间,不建议
void print(struct Person p)
{
	printf("Name:%s Age:%d ID:%d Score:%f\n", p.name, p.age, p.ID, p.score);
}

void test()
{
	struct Person person = { "Trump",70,250,59.9 };
	print(person);
}

在这里插入图片描述

struct Person
{
	char name[64];
	int age;
	int ID;
	double score;
};

//地址传递,每次4个字节
//如果是指针的话,代表拿到的是原始数据的内存空间,就有可能在使用过程中修改元数据的值
//为了规避地址传递的副作用,使用const
void print(const struct Person *p)
{
	printf("Name:%s Age:%d ID:%d Score:%f\n", p->name, p->age, p->ID, p->score);
}

void test()
{
	struct Person person = { "Trump",70,250,59.9 };
	print(&person);
}

在这里插入图片描述

6. 指针的指针(二级指针)

6.1 输出特性
在这里插入图片描述
在这里插入图片描述

void allocateSpace(int **temp)
{
	int* arr = malloc(sizeof(int) * 10);
	for (int i = 0; i < 10; ++i)
	{
		arr[i] = i + 1;
	}
	//指针间接赋值
	*temp = arr;
}

void print(int *arr,int len)
{
	for (int i = 0; i < len; ++i)
		printf("%d ", arr[i]);
}

void freeSpace(int  **arr)
{
	if (arr == NULL)
		return;
	if (*arr != NULL)
	{
		free(*arr);
		*arr = NULL;
		arr = NULL;
	}
}

void test()
{
	int* pArray = NULL;
	allocateSpace(&pArray);//取完地址指针升级,一级指针变为二级
	print(pArray, 10);
	freeSpace(&pArray);
	if (pArray == NULL) 
	{
		printf("\npArray被置空!\n");
	}
}

在这里插入图片描述
6.2 输入特性
二级指针做形参输入特性是指由主调函数分配内存
在这里插入图片描述

void print(int** arr, int len)
{
	for (int i = 0; i < len; i++)
	{
		printf("%d ", *arr[i]);
	}
}

void test()
{
	//堆上分配指针数组
	int** pArray = malloc(sizeof(int*) * 6);

	//栈上分配数据空间
	int a1 = 100;
	int a2 = 200;
	int a3 = 300;
	int a4 = 400;
	int a5 = 500;
	int a6 = 600;

	*(pArray + 0) = &a1;
	*(pArray + 1) = &a2;
	*(pArray + 2) = &a3;
	*(pArray + 3) = &a4;
	*(pArray + 4) = &a5;
	*(pArray + 5) = &a6;
	print(pArray, 6);
	
	//释放数组内存
	if (pArray != NULL)
	{
		free(pArray);
		pArray = NULL;
	}
}

在这里插入图片描述
在这里插入图片描述

void print(int** arr, int len)
{
	for (int i = 0; i < len; i++)
	{
		printf("%d ", *arr[i]);
	}
}
void test()
{
	int* pArray[5];//栈上开辟指针数组
	for (int i = 0; i < 5; ++i)
	{
		pArray[i] = malloc(4);//整形4个字节
		*(pArray[i]) = 100 + i;
	}
	print(pArray, 5);
	//释放堆内存
	for (int i = 0; i < 5; ++i)
	{
		if (pArray[i] != NULL)
		{
			free(pArray[i]);
			pArray[i] = NULL;
		}
	}
}

在这里插入图片描述
6.3 文件读写
在这里插入图片描述

void print(int** contents, int lines)
{
	for (int i = 0; i < lines; i++)
	{
		printf("%d行:%s", i+1, contents[i]);
	}
}

//释放文件数据内存
void freeFileSpace(char** contents, int lines)
{
	for (int i = 0; i < lines; ++i)
	{
		if (contents[i] != NULL)
		{
			free(contents[i]);
			contents[i] = NULL;
		}
	}
	free(contents);
	contents = NULL;
}

int getFIleLines(FILE* file)
{
	if (NULL == file)
	{
		return -1;
	}
	char buf[1024] = { 0 };
	int lines = 0;
	while (fgets(buf, 1024, file) != NULL)
	{
		++lines;
	}
	//恢复文件指针,指向文件起始位置
	fseek(file, 0, SEEK_SET);
	return lines;
}

void read(FILE* file, int lines, char **contents)
{
	if (NULL == file)
		return;
	if (NULL == contents)
		return;
	if (lines <= 0)
		return;
	//创建缓冲区
	char buf[1024] = { 0 };
	int  index = 0;
	while (fgets(buf, 1024, file) != NULL)
	{
		//printf("buf:%s", buf);
		int curLineLen = strlen(buf) + 1;
		//给当前行分配内存
		char *lineContent = malloc(sizeof(char) * curLineLen);
		//将行数据拷贝到空间中
		strcpy(lineContent, buf);
		contents[index++] = lineContent;
		memset(buf, 0, 1024);
	}
}

void test()
{
	//根据文件中每行的长度开辟内存空间
	//先读文件根据行数开辟指针数组
	FILE* file = fopen("./test.txt", "r");
	if (NULL == file)
	{
		printf("open error!");
		return;
	}
	//统计文件行数
	int lines = getFIleLines(file);
	printf("lines:%d\n", lines);
	
	char** pContents = malloc(sizeof(char*) * lines);//每个char *保存一行数据
	//读取文件内容
	read(file, lines, pContents);
	//打印文件内容
	print(pContents, lines);
	//释放文件数据
	freeFileSpace(pContents, lines);
	//关闭文件
	fclose(file);
	file = NULL;
}

在这里插入图片描述

7 位逻辑运算符

在这里插入图片描述
7.1 按位取反
在这里插入图片描述

void test() {
	int number = 2;//010   101负数使用补码存储:110 + 1 = 111-->-3
	printf("~number : %d\n", ~number);
}

在这里插入图片描述
7.2 位与 &
在这里插入图片描述
在这里插入图片描述

void test() {
	int number = 332;
	if ((number & 1) == 0) {
		printf("%d是偶数!\n",number);
	}
	else
		printf("%d是奇数!\n", number);
	number &= 0;//将number置零
}

在这里插入图片描述
7.3 位或 |
在这里插入图片描述
在这里插入图片描述

void test() {
	int num1 = 5; int num2 = 3;
	printf("num 1 | num2 =  %d\n", num1 | num2);
}

在这里插入图片描述
7.4 位异或 ^
在这里插入图片描述

void test() {
	int num1 = 5; int num2 = 9;//交换两个数不需要临时变量
	printf("num1:%d  num2:%d\n", num1, num2);
	num1 = num1 ^ num2;
	num2 = num1 ^ num2;
	num1 = num1 ^ num2;
	printf("num1:%d  num2:%d\n", num1,num2);
}

在这里插入图片描述

8 移位运算符

8.1 左移
在这里插入图片描述

void test() {
	//左移几位就相当于乘以2的几次方
	int num = 20;
	printf("number = %d\n", num << 1);
}

在这里插入图片描述
8.2 右移
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值