目录
前言
一、atoi函数实现
atoi()函数的功能:将字符串转换成整型数;atoi()会扫描参数nptr字符串,跳过前面的空格字符,直到遇上数字或正负号才开始做转换,而再遇到非数字或字符串时('\0')才结束转化,并将结果返回(返回转换后的整型数)。
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
//VALID 表示结果合法
//INVALID 表示结果非法
enum State
{
VALID,//合法
INVALID//非法
};
//默认结果可能非法,当正确转换后再改为合法
enum State state = INVALID;
int my_atoi(char *str)
{
//代表数字的正负
int flag = 1;
//长整型保证不会溢出
long long ret = 0;
assert(str);
state = INVALID;
//跳过空白字符
while(isspace(*str))
{
str++;
}
if(*str == '\0')
{
return 0;
}
//跳过正负号
if(*str == '+')
{
str++;
}
else if(*str == '-')
{
flag = -1;
str++;
}
//开始转换数字字符直到非数字字符
while(isdigit(*str))
{
ret = ret * 10 + flag * (*str-'0');
if((ret > INT_MAX) || (ret < INT_MIN))
{
return 0;
}
str++;
}
//正常停止
if(*str == '\0')
{
state = VALID;
return (int)ret;
}
else
{
//遇到非数字字符
return (int)ret;
}
}
int main()
{
char *p = "-1212212121212";
printf("%d\n", my_atoi(p));
return 0;
}
二、用宏将整数的二进制位奇数位和偶数位交换
🔑思路:
/ /00000000000000000000000000001010 - 10
//把10的所有偶数位保留下来,奇数位置0,再右移一位1
所以&上0xaaaaaaaa(10101010101010101010101010101010)
//00000000000000000000000000001010 >>1
//00000000000000000000000000000101
//把10的所有奇数位保留下来,偶数位置0,再左移一位
//所以&上0x55555555(010101010101010101010101010101)
//00000000000000000000000000000000 <<1
//00000000000000000000000000000000
#define SwapIntBit(n) (((n) & 0x55555555) << 1 | ((n) & 0xaaaaaaaa) >> 1)
※这个宏只能完成32位以内的整形,要想完成64位的,那就将5和a的数量翻倍即可
三、offsetof实现
该宏用于求结构体中一个成员在该结构体中的偏移量
size_t offsetof( structName, memberName );
//第一个参数是结构体的名字,第二个参数是结构体成员的名字。该宏返回结构体structName中成员memberName的偏移量。偏移量是size_t类型的。
实现:
#define offsetof(s, m) (size_t)&(((s *)0)->m)
StructType是结构体类型名,MemberName是成员名。具体操作方法是:
1、先将0转换为一个结构体类型的指针,相当于某个结构体的首地址是0。此时,每一个成员的偏移量就成了相对0的偏移量,这样就不需要减去首地址了。
2、对该指针用->访问其成员,并取出地址,由于结构体起始地址为0,此时成员偏移量直接相当于对0的偏移量,所以得到的值直接就是对首地址的偏移量。
3、取出该成员的地址,强转成size_t并打印,就求出了这个偏移量。
总结
建议再复习一下。