通讯录和内存动态管理

目录

(通讯录)动态增长版                

实现效果

找单身狗

题目

源码

思路

三个内存函数的模拟实现

模拟实现strncpy

模拟实现strncat

模拟实现atoi


(通讯录)动态增长版                

该版本通讯录在原版的基础上增加了检查容量函数,实现了通讯录的动态增长

//检查是否需要增容
int CheckSz(Contact* pc)
{


	if (pc->count == pc->sz)
	{
		PeoInfo* str = (PeoInfo*)realloc(pc->date, (pc->sz + ADD_SZ) * sizeof(PeoInfo));
		if (str == NULL)
		{
			perror("CheckSz:");
			return 0;
		}
		else
		{
			pc->date = str;
			pc->sz += ADD_SZ;
			printf("增容成功\n");
			return 1;
		}


	}


	return 1;




}

在使用添加函数时调用检查容量函数即可实现动态增长

实现效果

找单身狗

题目

一个数组中只有两个数字是出现一次,其他所有数字都出现了两次。

编写一个函数找出这两个只出现一次的数字。

例如:

有数组的元素是:1,2,3,4,5,1,2,3,4,6

只有5和6只出现1次,要找出5和6.

源码

void FindSingle(int* arr, int size,int* dog1,int* dog2)
{
    




    //计算所有数组异或结果ret   
    int i = 0;
    int ret = 0;
    for (i = 0; i < size; i++) {
        ret ^= arr[i];            
    }


    //计算ret第几位是1    
    int pos = 0;
    for ( i = 0; i < 32 ; i++)
    {
        if ((ret >> i )& 1 == 1)
        {
            pos = i;
            break;
        }
    }






    //计算第pos为1异或
    for (int i = 0; i < size; i++)
    {
        if (((arr[i] >> pos) & 1) == 1)
        {
           *dog1 ^= arr[i];
        }
        //计算第pos为0异或
        else
        {
            *dog2 ^= arr[i];
        }
    }








}


int main()
{
    int arr[] = { 1, 2, 3, 4, 5, 1, 2, 3, 4, 6 };
    int size = sizeof(arr) / sizeof(arr[0]);
    int dog1 = 0;
    int dog2 = 0;


    FindSingle(arr, size,&dog1,&dog2);




    printf("单身狗是%d %d",dog1,dog2);


    return 0;
}

思路

使用了异或的思想   相同为0  不同为1

(注意!异或比较的是二进制位 任何数与0的异或都为本身 而不是1)

1.计算所有数组异或结果ret   

2.计算ret第几位是1    
3.计算第pos为1异或

4.计算第pos为0异或

三个内存函数的模拟实现

模拟实现strncpy

从字符串中复制字符

#define _CRT_SECURE_NO_WARNINGS 1


#include <stdio.h>
#include <assert.h>




//char* strncpy(char* destination, const char* source, size_t num);




char* my_strncpy(char* des, const char* src, int num)
{


	     char* temp = des;
	
	
		assert(des != NULL);
		assert(src != NULL);
	
	
		while (*src && num--)
		{
			*des = *src;
			des++;
			src++;
		}
		
		*des = '\0';   //将\0拷贝
	
	
		return temp;






}








int main()
{






		char str1[] = "To be or not to be";
		char str2[40];
		char str3[40];


		
		my_strncpy(str2, str1, 8);


		my_strncpy(str3, str2, 5);


		puts(str1);
		puts(str2);
		puts(str3);


		return 0;
	}

模拟实现strncat

从字符串追加字符

#define _CRT_SECURE_NO_WARNINGS 1


#include <stdio.h>
#include <assert.h>






//char* strncat(char* destination, const char* source, size_t num);








char* my_strncat(char* des, const char* src,int num)
{
	assert(des);
	assert(src);




	char* temp = des;




	while (*des)
	{
		des++;
	}




	while (*src && num--)
	{
		*des++ = *src++;


	}


	*des = '\0';


	return temp;




}








int main()
{




	char str1[20];
	char str2[20];
	strcpy(str1, "To be ");
	strcpy(str2, "or not to be");
	my_strncat(str1,str2,6);
	puts(str1);








	return 0;
}

模拟实现atoi

将字符串转换为整数

#define _CRT_SECURE_NO_WARNING 1


#include <stdio.h>


#include <ctype.h>


#include <assert.h>


#include <limits.h>


//1.空指针
//2.空字符串
//3.空白字符
//4.数字超过范围
//




enum State
{
	TID,
	FID
}state = FID;//全局的转态,它的值标志返回的值是合法还是异常






int my_atoi(const char* str)
{
	int flag = 1;
	assert(str);//空指针


	if (*str == '\0')//空字符串
	{
		return 0;
	}
	//跳过空白字符
	while (isspace(*str))
	{
		str++;
	}
	if (*str == '-')
	{
		flag = -1;
		str++;
	}
	else if (*str == '+')
	{
		str++;
	}
	long long ret = 0;
	while (*str != '\0')
	{
		if (isdigit(*str))
		{
			ret = ret * 10 + flag * (*str - '0');
			if (ret > INT_MAX || ret < INT_MIN)
			{
				return 0;
			}
		}
		else
		{
			return (int)ret;
		}
		str++;
	}
	state = TID;
	return (int)ret;




}


int main()
{


	int ret = my_atoi("123");
	if (state == TID)
	{
		printf("%d\n", ret);
	}
	else
	{
		printf("非法返回:%d\n", ret);
	}






	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

比特大魔One

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值