700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > c++实现atoi()和itoa()函数(字符串和整数转化)

c++实现atoi()和itoa()函数(字符串和整数转化)

时间:2023-02-04 11:14:15

相关推荐

c++实现atoi()和itoa()函数(字符串和整数转化)

(0)

c++类型所占的字节和表示范围

c 语言里 类型转换那些事儿(补码 反码)

应届生面试准备之道

最值得学习阅读的10个C语言开源项目代码

一:起因

(1)字符串类型转化为整数型(Integer),还是字符串类型(String)转化为Double类型,这在java里面有非常好的内部函数,很easy的事情;

(2)但是在c里面没有Integer Double等包装类,由char[]数组转化为整数型就变得不那么简单了,atoi() itoa()在widows下面有,但是网上说linux 下好像没有 itoa() 函数,用 sprintf() 好了,但是本人测试了一下sprintf() sscanf()的效率很低。

(3)所以自己手动实现了一下atoi()(字符串转整数) itoa(整数转字符串)两个函数,有哪里不对的地方,大家指正。

(4)我也幼稚过 请看当初写的关于int --> string 的 blog

(插入———— begin)

(0)在区间(0,1)上任取三个数,则这三个数之和小于1的概率为?答案是1/6,怎么计算的,求详细解答?

设所取的三个数分别为 x、y、z ,则 0<x<1,0<y<1,0<z<1 ,

满足上述条件的点 P(x,y,z)构成一个棱长为 1 的正方体,体积为 V=1*1*1=1 ,

满足 x+y+z=1 的点是分别过(1,0,0)、(0,1,0)、(0,0,1)的平面,

而满足 x+y+z<1 的点位于正方体内、平面的下方,体积为 V1=1/3*1/2*1*1*1=1/6 (要是三个任意小于2的数呢?)

(1)先看一段程序

// test for begin#define fuc(a) ((a)*(a))//test for end// test for beginint aa = 5;cout << "fuc(a++): " << fuc(aa++) <<endl;//25aa = 5;cout << "fuc(++a): " << fuc(++aa) <<endl;//49aa = 5;cout << aa << aa++ << endl;//6,5aa = 5;cout << aa++ << aa << endl;// 5,5int b[7] = {1,2,3,4,5,7,8};int *ptr = (int*)(&b+1);// 现在的ptr指向数组长度的下一位置printf("%d,%d\n",*(b+1),*(ptr-1));// ptr-1指向b[len-1]最后一个元素cout << &b << "," << ptr << "," << b << "," << (*ptr) << endl;int d = 5;int c =10;int &ii = d;// 大哥啊,这是引用啊~~~哎~~~这都不会了,还笔试个毛啊,这都忘了,还面试个毛啊int *jj = &c;int *&kk = jj;// 从右往左读,指针的引用;//int*&p 是 指针的引用,它是一个 指针 的 别名 ,一般可以当成 指针 使用。cout << ii << endl;//test for end

解析

int *ptr=(int *)(&a+1)

【理论知识】:首先需要搞明白a,&a. a既是数据名,又是指向数组第一个元素的指针。

sizeof(a)=20, 此时a的类型为int[5]数组。

sizeof(*a)=4,因为有取值符*,表示把a当成一个指针(int*),而a指向数组的首地址,即a=&(a[0]),即sizeof(*a)=sizeof(*&(a[0]))=sizeof(a[0])=sizeof(int)=4。

*(a+1)中把a当成一个指针,a+1=a+sizeof(int),a+1指向a的下一个整形地址既&a[1]。因此*(a+1)=*(&a[1])=a[1]=2。

(&a+1)先取变量a的地址,并根据a的地址获得下一个与a同类型的相邻地址。根据前面所说的a的类型为int[5]数组。&a+1=&a+sizeof(5*int),因此&a+1指向的地址为&a[5](数组a[5]的下一个地址)。(int*)(&a+1)把这个相邻地址显式类型转换为int类型的地址int*ptr=(int*)(&a+1);所以ptr指向&a[5],并且ptr是一个int类型的指针。

ptr-1=ptr-sizeof(int),故ptr-1指向&a[4]。因此,*(ptr-1)的值即为a[4]=5。

【个人理解】:

a[5]即可以看成是一个一维数组,也可以看成是一个只有一行的二维数组a[1][5]。

所以a指向一维数组的首地址,即a=&a[0],a+1指向&a[1]。每次加的地址长度为sizeof(int).

而&a指向二维数组的首地址,即&a=&a[0][5],&a+1指向&a[1][5]。每次加的地址长度为sizeof(5*int).

(3)【题目】

Given a singly linked list L: L0→L1→…→Ln-1→Ln,

reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→…

You must do this in-place without altering the nodes' values.

【分析】

题目思路比较直接:

(1)找到链表的中间节点,把链表划分成2个子链表;如果原链表长度为奇数,那么第一个子链表的长度多1;

(2)翻转第二个子链表;

(3)交叉合并两个子链表。

例如{1,2,3,4,5,6,7}

(1)找到链表的中间节点为4,把链表划分成2个子链表:{1,2,3,4}和{5,6,7};

(2)翻转第二个子链表得到{7,6,5}

(3)交叉合并{1,2,3,4}和{7,6,5}得到{1,7,2,6,3,5,4}

///*version: 1.0author: hellogiserblog: /hellogiserdate: /5/30*/#include "stdafx.h"struct ListNode{int value;ListNode *next;};// find middle node of listListNode *FindMiddleNode(ListNode *head){if(NULL == head)return NULL;ListNode *fast = head, *slow = head;while(fast != NULL && fast->next != NULL){// move fast 2 stepsfast = fast->next->next;if (fast == NULL)break;// move slow 1 stepslow = slow->next;}return slow;}// reverse listListNode *ReverseList(ListNode *head){if(NULL == head || NULL == head->next)return head;ListNode *prev = NULL, *cur = head, *next = NULL;while(cur != NULL){// save nextnext = cur->next;// reversecur->next = prev;// update prev and curprev = cur;cur = next;}return prev;}// cross merge listListNode *CrossMergeList(ListNode *head1, ListNode *head2){if(NULL == head1)return head2;else if (NULL == head2)return head1;ListNode *node1 = head1, *node2 = head2;while(node2 != NULL){ListNode *temp1 = node1->next;ListNode *temp2 = node2->next;node1->next = node2;node2->next = temp1;// update node1 node2node1 = temp1;node2 = temp2;}return head1;}// reorder listListNode *ReOrderList(ListNode *head){if(NULL == head || NULL == head->next)return head;// find middle node of listListNode *middle = FindMiddleNode(head);// split into 2 listsListNode *head1 = head;ListNode *head2 = middle->next;// detach the 2 listsmiddle->next = NULL;// reverse list2head2 = ReverseList(head2);// cross merge 2 listsreturn CrossMergeList(head1, head2);}

(插入——————end)

二:实现

(1)atoi()函数原型:int atoi(char *str) 头文件 stdlib.h

函数用途:将字符串转换成一个整数值

输入参数:str 待转换为整型数的字符串

返回值:成功返回转换后的数值,失败则返回0.

(2)代码实现

int my_atoi(char s[]){int i,n,sign;for(i=0;isspace(s[i]);i++); //跳过空白,isspace()这个函数在type.h头文件中;也可以s[i]==' '实现sign=(s[i]=='-')?-1:1;if(s[i]=='+'||s[i]=='-')//跳过符号位i++;for(n=0;isdigit(s[i]);i++)n=10*n+(s[i]-'0'); //将数字字符转换成整形数字,isdigit()这个函数在type.h头文件中;也可以s[i]>='0' && s[i]<='9''实现; 0x30是 '0'return sign*n;}

(3)itoa()函数的原型:char *itoa( int value, char *str,int radix)

函数用途:将整数型值value转换成一个字符串

输入参数:value待转换的整型数 ;str目标字符串的地址,即返回值;radix:转换后的进制数,可以是10进制、16进制等。

返回值:成功返回一个字符串.

(4)代码实现

/*Converts an int or long into a character string将一个整数转化为字符串*/char* my_itoa(int n,char str[]){int i,j,len,sign;if((sign=n)<0) //记录符号n=-n; //使n成为正数i=0;do{str[i++]=n%10+'0'; //取下一个数字}while((n/=10)>0);//循环相除if(sign<0)str[i++]='-';str[i]='\0';len = i;//for(j=len-1,i=0;j>i;j--,i++) //生成的数字是逆序的,所以要交换{str[j] ^= str[i];str[i] ^= str[j];str[j] ^= str[i];}return str;}

(5) 主函数测试

#include "stdio.h"#include "ctype.h"#include "stdlib.h"int main(){int n;char str[32],*ans;ans = my_itoa(-123,str);printf("自编自导的整形转字符串函数my_itoa():%s %s\n",ans,str);printf("系统自带的整形转字符串函数itoa():%s %s\n",itoa(-1,str,16),str);printf("自编自导的字符串转整形函数my_atoi():%d\n",my_atoi(" 22qqq"));printf("系统自带的字符串转整形函数atoi():%d\n",atoi(" -2qqq "));system("pause");return 0;}

(6)测试结果:

三:不足之处

(1)itoa()函数的原型:char *itoa( int value, char *str,int radix),自己并未完全实现,只是简单的实现了10进制的

(2)下面会改进的,上面有不足之处,请大神指教

(3)itoa()函数的原型:char *itoa( int value, char *str,int radix),自己简单的实现,默认是实现了10进制的

char __itoa[] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};const unsigned int MY_MAX = 0xFFFFFFFFu;char* my_itoa2(int n,char str[],int radix=10){int i,j,len,sign;unsigned int tmp;i = 0;if(n<0) //{tmp = MY_MAX + n + 1;// 这样貌似可以了,按照取反加一的方式进行的do{str[i++]=__itoa[tmp%radix]; //取下一个数字}while((tmp/=radix)>0);//循环相除}else{do{str[i++]=__itoa[n%radix]; //取下一个数字}while((n/=radix)>0);//循环相除}str[i]='\0';len = i;//for(j=len-1,i=0;j>i;j--,i++) //生成的数字是逆序的,所以要交换{str[j] ^= str[i];str[i] ^= str[j];str[j] ^= str[i];}return str;}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。