找单身狗,atoi的模拟实现,offseto宏的实现

一:找单身狗

  描述:一个数组中只有两个数字是出现一次,其他所有数字都出现了两次。编写一个函数找出这两个只出现一次的数字。

思路:(整体把五和六分到两个组里面去)(异或   相同为0;相异为1(支持交换律))

过程

1:计算5,6的哪一位为1--n

2:以第n位为标准,第n位为1的放一组;第n位为0的放一组

 

 代码实现:

#include<stdio.h>
int main()

{
int arr[] = { 1,2,3,4,5,1,2,3,4,6 };
        //所有数字异或
int i = 0;
int sz = sizeof(arr) / sizeof(arr[0]);
int ret = 0;
for (i = 0; i < sz; i++)
{
ret ^= arr[i];
}
//ret就是5^6的结果,二进制中一定有1
//计算ret的第几位是1
int pos = 0;
for (i = 0; i < 32; i++)
{
if (((ret >> i) & 1) == 1)
{
pos = i;
break;
}
}
//ret的第pos位是1
//把arr数组中的每个元素的第pos位为1的数字异或在一起
int num1 = 0;
int num2 = 0;
for (i = 0; i < sz; i++)
{
if (((arr[i] >> pos) & 1) == 1)
{
num1 ^= arr[i];
}
else
{
num2 ^= arr[i];
}
}
printf("%d %d\n", num1,num2);
return 0;
}

运行结果:

 二:模拟实现atoi(把字符串转换成对应的数字)

我们先对它的功能进行简单的了解:

#include <stdlib.h>
#include<stdio.h>

int main()
{
int ret = atoi("123");
printf("%d\n", ret);
return 0;
}

运行结果:

 现在我们来进行对atoi的模拟实现;而在模拟实现之前我们要先考虑多种异常情况,例如:

   首先第一,二种为空指针和空字符串的时候是不允许的,所以我们要判断一下排除掉;然后第五和第六种是非字符串和值太大也是不被允许的;所以在码代码之前都要一一排除掉;

模拟实现:

#include <stdlib.h>
#include <ctype.h>
#include<limits.h>
#include<ctype.h>

enum Status
{
VALID,
INVALID
};
enum Status status = INVALID;

int my_atoi(const char* str)
{
if (str == NULL)
{
return 0;
}
if (*str == '\0')
{
return 0;
}
//空白字符
while (isspace(*str))
{
str++;
}
int flag = 0;
if (*str=='+')
{
flag = 1;
str++;
}
else if (*str == '-')
{
flag = -1;
str++;

} 
//处理数字字符
long long ret = 0;
while (isdigit(*str))
{
ret = ret * 10 + flag * (*str - '0');
if (ret<INT_MIN || ret>INT_MAX)
{
return  0;
}
str++;
}
if (*str == '\0')
{
status = VALID;
return (int)ret;
}
else
{
return (int)ret;
}
}
int main()
{
int ret = my_atoi("-123");
if (status == VALID)
printf("合法转换:%d\n", ret);
else
printf("非法数据转换:%d\n", ret);
return 0;
}

运行结果:

 三:offseto宏的实现

  计算结构体中某变量相对于首地址的偏移

struct S
{
char a; 
int b;
char c;
};

#define OFFSETOF(s_type,m_name)    (int)&(((s_type*)0)->m_name)
int main()
{

printf("%d\n", OFFSETOF(struct S, a));
printf("%d\n", OFFSETOF(struct S, b));
printf("%d\n", OFFSETOF(struct S, c));
return 0;
}

运行结果:

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值