atio函数和宏offset的介绍

前言

本章带大家一起认识一些在我们C语言标准库中的函数

atoi函数

int atio(const char* str);

头文件:

#include<stdlib.h>

参数:
str指向常量字符串起始位置的指针
函数介绍:

①解析C语言字符串str,将其内容解释为整数,返回一个int类型的值。
②函数丢弃空白字符,直到第一个非空白字符被找到,从该元素开始取一个可选的初始加号或减号,后面跟着以10基数的数字,并将它们解释为数值。(注意:初始加号或者减号后面跟着的必须是字符数字,只出现一次,其他情况下出现为非字符数字)
③如果字符串str中的第一个非空字符不是有效的整数,或者字符串str为空或字符串仅包含空白字符序列,则不执行转换,返回值为0。
④字符串中包含了非字符数字的字符,则非字符数字之前的字符数字(有效字符)直接被返回,后面的该非字符数字及其之后有效字符数字都不能被转换。
⑤如果函数转换成功,函数将转换之后的in类型的整数返回。如果转换后的值超过了int类型整数的取值范围,会导致未定义行为。

函数的使用案例:

#include<stdio.h>
#include<stdlib.h>
int main()
{
	int i = atoi("");//字符串什么都没有
	int a = atoi("   ");//字符串都为空字符
	int b = atoi("a123");//第一个字符非数字字符
	int c = atoi("000123#456");//字符串中间为非数字字符
	int d = atoi("99999999999999999999999");
	//有效字符的值超过int类型的取值范围
	int e = atoi("    +-123456");//加减号同时出现
	int m = atoi("  +123456");//只有减号出现
	int n = atoi("  -123456");//只有加号出现
	printf("%d\n", i);
	printf("%d\n", a);
	printf("%d\n", b);
	printf("%d\n", c);
	printf("%d\n", d);
	printf("%d\n", e);
	printf("%d\n", m);
	printf("%d\n", n);
	return 0;
}

代码运行的结果为:
在这里插入图片描述
atoi函数的模拟实现:

//需要考虑的情况
//空白字符
//+/-号
//溢出
//""空字符串
//空指针
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<ctype.h>
enum State
{
	INVALID,
	VALID
}state= INVALID;//默认表示非法
int my_atoi(const char* str)
{
	assert(str);
	if (*str == '\0')
	{
		return 0;
	}
	//isspace判断是否为空白字符
	//是空白字符为真,否则为假
	//跳过空白字符
	while (isspace(*str))
	{
		str++;
	}
	int flag = 1;//判断初始正负号
	if (*str == '+')
	{
		str++;
	}
	else if(*str=='-')
	{
		flag = -1;
		str++;
	}
	long long ret = 0;//存放返回值
	while (*str)
	{
	//isdigit判断是否为字符数字
		if (isdigit(*str))
		{
			ret = ret * 10 + flag * (*str - '0');
			if (ret > INT_MAX)
			{
				return INT_MAX;
			}
			else if (ret < INT_MIN)
			{
				return INT_MIN;
			}
		}
		else
		{
			return (int)ret;
		}
		str++;
	}
	state = VALID;
	return (int)ret;
}
int main()
{
	int ret=my_atoi("123456");
	if (state == VALID)
	{
		printf("%d\n", ret);
	}
	else
	{
		printf("非法字符串转换:%d\n",ret);
	}
	return 0;
}

代码运行的结果:
在这里插入图片描述

宏offsetof

在这里插入图片描述
宏使用形式:

offsetof(type, member)

头文件:

#include<stddef.h>

参数介绍:

type
为有效成员指示符的类型,一般为结构体或者联合体类型
member
为type类型的成员

宏的介绍:

该函数形式的宏返回的是结构体成员或联合体成员的偏移值(成员距离0偏移量的位置),单位为字节。

宏offsetof的使用例子:

#include<stddef.h>
#include<stdio.h>
struct S
{
	char c1;
	int i;
	char c2;
};
int main()
{
	printf("%d\n", offsetof(struct S,c1));
	printf("%d\n", offsetof(struct S, i));
	printf("%d\n", offsetof(struct S, c2));
	return 0;
}

代码运行的结果:
在这里插入图片描述
宏offsetof的模拟实现:

//宏的模拟实现
#include<stdio.h>
struct S
{
	char c1;//1/8 对齐数为1
	int i;//4/8 对齐数为4
	char c2;//1/8 对齐数为1
};
#define my_offsetof(type,member)  (int)&(((type*)0)->member)
int main()
{
	printf("%d\n",my_offsetof(struct S,c1));
	printf("%d\n", my_offsetof(struct S, i));
	printf("%d\n", my_offsetof(struct S, c2));
	return 0;
}

代码运行的结果:
在这里插入图片描述

图形理解:
在这里插入图片描述
解释:

通过图形观察我们可以发现,结构体成员的起始地址和0偏移量地址相减的个数(地址之间的字节数)刚好就是该结构体成员的偏移量。既然这样,我们把0偏移量地址设为0,那么结构体成员变量的起始地址刚好也表示偏移量;我们在定义宏my_offsetof的时候,把整型变量0强转为结构体类型的指针变量,指向结构体里面的成员,然后取成员变量的地址随即强转为整型,得到便是该成员的偏移量。

总结

本章为大家介绍了函数atoi和宏offsetof的使用,希望对大家认识函数atoi和宏offsetof有些许帮助!最后感谢大家阅读,若有不对,欢迎指正!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值