(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 begin
int aa = 5;
cout << "fuc(a++): " << fuc(aa++) <<endl;//25
aa = 5;
cout << "fuc(++a): " << fuc(++aa) <<endl;//49
aa = 5;
cout << aa << aa++ << endl;//6,5
aa = 5;
cout << aa++ << aa << endl;// 5,5 int 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.0
author: hellogiser
blog: http://www.cnblogs.com/hellogiser
date: 2014/5/30
*/
#include "stdafx.h" struct ListNode
{
int value;
ListNode *next;
}; // find middle node of list
ListNode *FindMiddleNode(ListNode *head)
{
if(NULL == head)
return NULL;
ListNode *fast = head, *slow = head;
while(fast != NULL && fast->next != NULL)
{
// move fast 2 steps
fast = fast->next->next;
if (fast == NULL)
break;
// move slow 1 step
slow = slow->next;
}
return slow;
} // reverse list
ListNode *ReverseList(ListNode *head)
{
if(NULL == head || NULL == head->next)
return head;
ListNode *prev = NULL, *cur = head, *next = NULL;
while(cur != NULL)
{
// save next
next = cur->next;
// reverse
cur->next = prev;
// update prev and cur
prev = cur;
cur = next;
}
return prev;
} // cross merge list
ListNode *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 node2
node1 = temp1;
node2 = temp2;
}
return head1;
} // reorder list
ListNode *ReOrderList(ListNode *head)
{
if(NULL == head || NULL == head->next)
return head; // find middle node of list
ListNode *middle = FindMiddleNode(head);
// split into 2 lists
ListNode *head1 = head;
ListNode *head2 = middle->next;
// detach the 2 lists
middle->next = NULL;
// reverse list2
head2 = ReverseList(head2);
// cross merge 2 lists
return 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;
}

c++实现atoi()和itoa()函数(字符串和整数转化)的更多相关文章

  1. 面试:atoi() 与 itoa()函数的内部实现(转)

    原 面试:atoi() 与 itoa()函数的内部实现 2013年04月19日 12:05:56 王世晖 阅读数:918   #include <stdio.h> #include < ...

  2. atoi()和itoa()函数详解以及C语言实现

    atoi()函数 atoi()原型:  int atoi(const char *str ); 函数功能:把字符串转换成整型数. 参数str:要进行转换的字符串 返回值:每个函数返回 int 值,此值 ...

  3. c语言实现atoi和itoa函数。

    首先看atoi函数: C语言库函数名: atoi 功 能: 把字符串转换成整型数. 名字来源:ASCII to integer 的缩写. 原型: int atoi(const char *nptr); ...

  4. atoi和itoa函数的实现方法

    atoi的实现: #include<iostream> using namespace std; int atio1(char *s) { int sign=1,num=0; if(*s= ...

  5. MYSQL 函数 字符串到整数

    SELECT CAST('002' AS signed) 结果为2 SELECT CAST('125e342.83' as signed) 结果为 125

  6. 编程算法 - 把字符串转换为整数 代码(C)

    把字符串转换为整数 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 写一个函数StrToInt, 模拟atoi的功能, 把字符串转换为整数. 须 ...

  7. [c/c++] programming之路(24)、字符串(五)——字符串插入,字符串转整数,删除字符,密码验证,注意事项

    1.将字符串插入到某位置(原字符串“hello yincheng hello cpp hello linux”,查找cpp,找到后在cpp的后面插入字符串“hello c”) 需要用到strstr字符 ...

  8. C语言数字与字符串转换 atoi()函数、itoa()函数、sprintf()函数

    在编程中经常需要用到数字与字符串的转换,下面就总结一下. 1.atoi() C/C++标准库函数,用于字符串到整数的转换. 函数原型:int atoi (const char * str); #inc ...

  9. C语言itoa()函数和atoi()函数详解(整数转字符C实现)

    1.int/float to string/array: C语言提供了几个标准库函数,可以将任意类型(整型.长整型.浮点型等)的数字转换为字符串,下面列举了各函数的方法及其说明. ● itoa():将 ...

随机推荐

  1. hibernate 数据关联一对一 3.2

    第一种一对一 person和card,card的id即作为主键,又作为外键  // 各村对方的一个对象 public class Person { private Integer id; privat ...

  2. Java学习之自定义异常

    1 package com.gh; import java.util.Scanner; /** * 自定义异常 * @author ganhang * */ public class Exceptio ...

  3. jQuery报错:Uncaught ReferenceError: $ is not defined

    在使用jQuery的时候,发现有如下报错: Uncaught ReferenceError: $ is not defined  (anonymous function) 出现这个报错的原因: 1.j ...

  4. Android显示GIF动画完整示例(二)

    MainActivity如下: package cc.testgif2; import android.os.Bundle; import android.app.Activity; /** * De ...

  5. c#中的委托使用(方法的调用, 和类的实话)

    方法的调用 delegate int test1(int a); class Program { static int num = 10; static void Main(string[] args ...

  6. iOS开发中两个不错的宏定义

    /** Synthsize a weak or strong reference. Example: @weakify(self) [self doSomething^{ @strongify(sel ...

  7. c/c++字符数组和字符串大揭秘

    第一:写这篇文章源于我对'\0'和“\0”的探讨 当我对char a []="\0"; int size_a=sizeof(a); //结果为2 当时我很纳闷字符串不是以'\0'结 ...

  8. java读文件的几个类

    链接地址:http://blog.sina.com.cn/s/blog_407a68fc0100f628.html 最初Java是不支持对文本文件的处理的,为了弥补这个缺憾而引入了Reader和Wri ...

  9. SQLite3的使用(用到了dll)good

    1.下载sqlite3相关文件sqlite3.dll.sqlite3.h(可从http://download.csdn.net/detail/mingxia_sui/5249070下载),添加到工程的 ...

  10. 基于springmvc的简单增删改查实现---中间使用到了bean validation

    package com.kite.controller; import java.util.HashMap; import java.util.Map; import javax.validation ...