atoi函数解析以及自定义类型经典练习题

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: atoi函数解析以及自定义类型经典练习题

今天也是清明节,但奈何学校只放一天假,那就只能来简简单单写个博客了,今天要写的自己对atoi函数的理解吧。还有发现了几道自定义类型的经典练习,像结构体,联合体也是有的,就写到博客分享一下。


常常会回顾努力的自己,所以要给自己的努力留下足迹。


atoi的概念

在 C 语言中, atoi 函数是一个用于将字符串转换为整数的库函数。它的全称是 atoi ,代表"ASCII to Integer",即把字符串表示的 ASCII 码值转换为整数。


atoi 函数的声明如下:

 

int atoi(const char *str);


参数:

-  str :指向要转换的字符串的指针。字符串中如果前面为空格该函数会省略掉前面的空格,直到遇到第一个数字字符。



返回值:

- 如果转换成功, atoi 函数返回转换后的整数。


- 如果 str 为空指针或不符合整数表示形式, atoi 函数返回 0。

函数的细节:


 atoi 函数只转换字符串的前一部分,直到遇到非数字字符或字符串结束。

 atoi 函数不检查字符串是否超出整数范围,如果转换的结果超出了整数范围,结果可能不正确。

由于 atoi 函数不检查字符串的有效性,可能会导致缓冲区溢出等安全问题。因此,在使用 atoi 函数时,应该确保输入的字符串是有效的整数表示形式。


下面是就简单给大家举一个示例代码的例子,演示了如何使用 atoi 函数将字符串转换为整数:

 

 

#include <stdio.h>
#include <stdlib.h>
 
 
int main() {
    // 定义一个字符串
    char str[] = "12345";
    int num;
 
    // 将字符串转换为整数
    num = atoi(str);
 
    // 输出转换后的整数
    printf("转换后的整数为:%d\n", num);
 
    return 0;
}

 

在这个示例中,定义了一个字符串 str ,它表示一个整数"12345"。然后,调用 atoi 函数将字符串转换为整数,并将结果存储在变量 num 中。最后,使用 printf 函数输出转换后的整数。


需要注意的是, atoi 函数返回的是一个整数值,如果需要将结果存储在非整数类型的变量中,需要进行类型转换。


代码演示atoi细节:

int main() {
  // 定义一个字符串
  char str[] = "   -12 aaee345";
  int num;
 
  // 将字符串转换为整数
  num = atoi(str);
 
  // 输出转换后的整数
  printf("转换后的整数为:%d\n", num);
 
  return 0;
}


这里再字符串没遇到数字字符时会过滤掉空格,直到遇到数字字符”+“,”-“号,这时在这之后再遇到任何不是数字字符的字符都会直接结束函数。

如上方代码,在省略完函数前方的空格后,函数遇到-,1,2.后,在遇到空格直接结束函数,所以这里的结果为-12.


再看一下一段代码:

int main() {
  // 定义一个字符串
  char str[] = "  -  12 aaee345";
  int num;
 
  // 将字符串转换为整数
  num = atoi(str);
 
  // 输出转换后的整数
  printf("转换后的整数为:%d\n", num);
 
  return 0;
}

这个只要按照我上面的说法也是很简单判断的,这里函数先是省略掉前面的空格然后识别到”-“,之后是空格,不是数字字符,直接结束函数,因为在此之前没有读取到任何数字字符所以这里的结果就是0.


总结:在atoi函数遇到第一个”+“,”-“,或数字字符后在遇到任何非 数字字符的函数则直接结束函数。

自定义类型经典练习题

诸君请看题呀

一、

 
#include <stdio.h>
#include <stdlib.h>
 
#define A 2
#define B 3
#define MAX_SIZE A+B
 
struct _Record_Struct
{
  unsigned char a : 4;
  unsigned char b : 2;
  unsigned char c;
  unsigned char d : 1;
}s;
 
int main()
{
  size_t num=sizeof(s)* MAX_SIZE;
 
  printf("%d\n", num);
 
 
  return 0;
}


大家伙觉得这道题的打印结果是什么呢,注意这道题除了考验一下我们对结构体位段知识的掌握,还设了一个坑点哦。

这里要知道打印结果就需要先知道位段结构体的大小 ,那么这里我们来求一求这个位段结构体的大小。如下图:这里求位段结构体的大小之前已发过文章,还没看过的小伙伴可以先去看看唔

这里我们成功求到这个结构体的大小,然后再看到这里,size_t num=sizeof(s)* MAX_SIZE;

在开头我们定义了


#define A 2

#define B 3

#define MAX_SIZE A+B

那我们一想,那不就是结构体大小再乘上MAX_SIZE不就可以了,然后3*5=15.然后答案真的是15吗。


很显然我之前说的坑点就是在这里,在这里答案是9.为什么呢?


在这里size_t num=sizeof(s)* MAX_SIZE;等价于size_t num=sizeof(s)* 2+3;


大家再看看这样后结果是不是就是9了,这里#define 只是单纯的变名,所以当用到时我们要将其变的东西原样抄下来即可。故这里的答案为9.


二、

int main()
{
    unsigned char s[4];
    struct tagPIM
    {
        unsigned char a;
        unsigned char b : 1;
        unsigned char c : 2;
        unsigned char d : 3;
    }*p;
    p = (struct tagPIM*)s;
    memset(s, 0, 4);
    p->a = 2;
    p->b = 3;
    p->c = 4;
    p->d = 5;
    printf("%02x %02x %02x %02x\n", s[0], s[1], s[2], s[3]);
    return 0;
}


这道题也是一道有关结构体位段的题目,而且还是具有一点难度的,那么接下来就一一解剖一下这道题吧。


首先上面的代码定义了一个char类型数组和结构体,并且创建了一个结构体指针,然后这道题重点就来了。


这里上面的题目当中开始把数组地址(数组名s)强制转化为结构体指针赋值给 struct tagPIM *p


然后再开始以位段结构体的形式进行对内存里赋值,这里的内存也是数组的内存,也是会影响函数的。


赋值阶段:


代码先是利用memset函数将数组中的4个字节的内存全部赋值为0。


再然后进行了这样的赋值


   p->a = 2;

   p->b = 3;

   p->c = 4;

   p->d = 5;


这里我们的成员a没有限定成员的大小所以依旧占据内存的一个字节,所以s[0]为2。


然后到下面重点了,我们画图来理解。

如上面所说这里我们已经算出第二个字节的内存里存储的数据,因为后面两个字节并未赋值到,所以还为0,综上所述这里打印的结果应该为02 29 00 00。


三、写一个用联合体判断当前机器的是大端还是小端储存。

参考代码如下:

int check_sys()
{
  union
  {
    int i;
    char c;
  }un;
  un.i = 1;
  return un.c;
}
 
int main()
{
  int ret = check_sys();
  if(ret == 1)
  {
    printf("小端\n");
  }
  else
  {
    printf("大端\n");
  }
  return 0;
}

正如上面所写,我们定义一个联合体并创建,成员一个为int类型,一个为char类型,我们知道联合体共用一块内存,而且char的内存是在低地址处。那么这时我们就先给int数据赋值一个1.


我们要知道1为一个整形十六进制为 00 00 00 01,那么此时最后两个数01为低位,我们只需要取地址的数据看是否为1,就可以判断出机器是大端还是小端


此时我们就看机器是大端还是小端,就可以返回char c,处的数据,这里为低地址的内存,如果此时数据为1,说明该机器把低位是数据放到低地址处,所以为小端储存模式。反之则为大端。

文章已到末尾

常常会回顾努力的自己,所以要给自己的努力留下足迹。

目录
相关文章
|
28天前
|
SQL 数据挖掘 测试技术
南大通用GBase8s数据库:LISTAGG函数的解析
南大通用GBase8s数据库:LISTAGG函数的解析
|
22天前
|
C语言 开发者
【C语言】断言函数 -《深入解析C语言调试利器 !》
断言(assert)是一种调试工具,用于在程序运行时检查某些条件是否成立。如果条件不成立,断言会触发错误,并通常会终止程序的执行。断言有助于在开发和测试阶段捕捉逻辑错误。
34 5
|
29天前
|
机器学习/深度学习 自然语言处理 语音技术
揭秘深度学习中的注意力机制:兼容性函数的深度解析
揭秘深度学习中的注意力机制:兼容性函数的深度解析
|
3月前
|
存储 前端开发 JavaScript
前端基础(十二)_函数高级、全局变量和局部变量、 预解析(变量提升)、函数返回值
本文介绍了JavaScript中作用域的概念,包括全局变量和局部变量的区别,预解析机制(变量提升),以及函数返回值的使用和类型。通过具体示例讲解了变量的作用域、函数的返回值、以及如何通过return关键字从函数中返回数据。
25 1
前端基础(十二)_函数高级、全局变量和局部变量、 预解析(变量提升)、函数返回值
|
2月前
|
数据处理 Python
深入探索:Python中的并发编程新纪元——协程与异步函数解析
深入探索:Python中的并发编程新纪元——协程与异步函数解析
31 3
|
2月前
|
机器学习/深度学习 算法 C语言
【Python】Math--数学函数(详细附解析~)
【Python】Math--数学函数(详细附解析~)
|
2月前
|
安全 编译器 C++
【C++篇】C++类与对象深度解析(三):类的默认成员函数详解
【C++篇】C++类与对象深度解析(三):类的默认成员函数详解
25 3
|
3月前
|
设计模式 存储 算法
PHP中的设计模式:策略模式的深入解析与应用在软件开发的浩瀚海洋中,PHP以其独特的魅力和强大的功能吸引了无数开发者。作为一门历史悠久且广泛应用的编程语言,PHP不仅拥有丰富的内置函数和扩展库,还支持面向对象编程(OOP),为开发者提供了灵活而强大的工具集。在PHP的众多特性中,设计模式的应用尤为引人注目,它们如同精雕细琢的宝石,镶嵌在代码的肌理之中,让程序更加优雅、高效且易于维护。今天,我们就来深入探讨PHP中使用频率颇高的一种设计模式——策略模式。
本文旨在深入探讨PHP中的策略模式,从定义到实现,再到应用场景,全面剖析其在PHP编程中的应用价值。策略模式作为一种行为型设计模式,允许在运行时根据不同情况选择不同的算法或行为,极大地提高了代码的灵活性和可维护性。通过实例分析,本文将展示如何在PHP项目中有效利用策略模式来解决实际问题,并提升代码质量。
|
1月前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
76 2
|
1天前
|
存储 设计模式 算法
【23种设计模式·全精解析 | 行为型模式篇】11种行为型模式的结构概述、案例实现、优缺点、扩展对比、使用场景、源码解析
行为型模式用于描述程序在运行时复杂的流程控制,即描述多个类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务,它涉及算法与对象间职责的分配。行为型模式分为类行为模式和对象行为模式,前者采用继承机制来在类间分派行为,后者采用组合或聚合在对象间分配行为。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象行为模式比类行为模式具有更大的灵活性。 行为型模式分为: • 模板方法模式 • 策略模式 • 命令模式 • 职责链模式 • 状态模式 • 观察者模式 • 中介者模式 • 迭代器模式 • 访问者模式 • 备忘录模式 • 解释器模式
【23种设计模式·全精解析 | 行为型模式篇】11种行为型模式的结构概述、案例实现、优缺点、扩展对比、使用场景、源码解析

推荐镜像

更多