int数组转换成char数组进一步思考及5种实现方法

// printfTest.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"

#include<iostream>
#include<stdlib.h>
#include<string>
#include <limits>
using namespace std;

//


//原理:  使用库函数,拷贝内存; 
void method1()
{
	long a=129;
	char s[4]={0};
	memcpy(s,&a,sizeof(long));//
	printf("%x %x %x %x\n",s[0],s[1],s[2],s[3]);

	//这里有问题,当a的值小于等于128时,都没问题,也就是说,s[0]可以存放一个较小的整数
	//但是,当a的值大于128时,会越界,不会自动截断,不会把剩下的部分放到s[1]中
	//



	//数组.........
}
/*******************************
void *memcpy(void *dest, const void *src, size_t n);
从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中
*******************************/


/********************************
int printf(const char *format,[argument]);
格式输出,它是c语言中产生格式化输出的函数(在 stdio.h 中定义)。用于向终端(显示器、控制台等)输出字符。
通常意义上format的格式如下:
%[flags][width][.prec][F|N|h|l]type
规定输出数据的格式,具体如下:[1]
type
type的字符用于规定输出数据的类型,含义如下:
字符
对应数据类型
含义
d、i
int
接受整数值并将它表示为有符号的十进制整数,i是老式写法
o
unsigned int
无符号8进制整数
u
unsigned int
无符号10进制整数
x、X
unsigned int
无符号16进制整数,x对应的是abcdef,X对应的是ABCDEF
f
float或double
单精度浮点数或双精度浮点数
e、E
double
科学计数法表示的数,此处"e"的大小写代表在输出时用的“e”的大小写
g、G
double
使用以上两种中最短的形式,大小写的使用同%e和%E
c
char
字符型。当接受值为字符串时打印字符串中的第一个字符,可以把输入的数字按照ASCII码相应转换为对应的字符
s、S
char *、wchar_t *
字符串。输出字符串中的字符直至字符串中的空字符(字符串以'\0‘结尾,这个'\0'即空字符)
p
void *
以16进制形式输出指针nint *到此字符之前为止,一共输出的字符个数,不输出文本
%
不输入
不进行转换,输出字符‘%’(百分号)本身
注:%g、%G在小数点位数四位或指数大于等于精度时用%e、%E,否则用%f。
flags
规定输出样式,取值和含义如下:
字符
字符名称
说明
空白
右对齐,左边填充空格
-
减号
左对齐,右边填充空格
+
加号
在数字前增加符号 + 或 -
0
数字零
将输出的前面补上0,直到占满指定列宽为止(不可以搭配使用“-”)
空格
输出值为正时加上空格,为负时加上负号
********************************/

/*原理:移位,强制转换*/
void method2()
{
	long a=134242304;
	char s[4];
	s[0]=(char)a;
	s[1]=(char)(a>>8);
	s[2]=(char)(a>>16);
	s[3]=(char)(a>>24);
	printf("%x %x %x %x\n",s[0],s[1],s[2],s[3]);
}

/*原理:  取a的地址,强制转化为char*,(指针占一个字节,正好四个字节),然后解引用取值并赋给s[i];*/  
void method3()
{
	long a=134242304;
	char s[4]; 
	for(int i = 0;i<4;i++)  
	{  
		s[i] = *((char*)&a+i);  
	}
	printf("%x %x %x %x\n",s[0],s[1],s[2],s[3]);  
}

//把uchar中的数据还原成long 
void rmethod()
{
	unsigned char ch[4]={0x00,0x60,0x00,0x08};
	unsigned long length=0;
	//以下操作完成char型数组到long型的转换
	//第一种方法
	length=(unsigned long)ch[0] | (unsigned long)ch[1]<<8 | (unsigned long)ch[2]<<16 | (unsigned long)ch[3]<<24;
	cout<<length<<endl;
}

//注意与函数 itoa\atoi\ltoa\atol区分,这些函数是把 123变成"123",或者相反。  
void ft()
{
	int number = 134242304;
	char st[25];
	itoa(number, st, 10); //按十进制转换
	ltoa(number, st, 10);
	printf("integer = %d st = %s\n", number, st);
	printf("%x %x %x %x\n",st[0],st[1],st[2],st[3]);
	itoa(number, st, 16); //按16进制转换
	printf("integer = %d st = %s\n", number, st);
	printf("%x %x %x %x\n",st[0],st[1],st[2],st[3]);
}

int _tmain(int argc, _TCHAR* argv[])
{
	method1();
	/*method2();
	method3();
	rmethod();
	ft();*/
	getchar();

	return 0;  
}

//sprintf(CharArray, "%d", IntegerArray[i]);

  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
指针数组数组指针的区别 数组指针(也称行指针) 定义 int (*p)[n]; ()优先级高,首先说明p是一个指针,指向一个整型的一维数组,这个一维数组的长度是n,也可以说是p的步长。也就是说执行p+1时,p要跨过n个整型数据的长度。 如要将二维数组赋给一指针,应这样赋值: int a[3][4]; int (*p)[4]; //该语句是定义一个数组指针,指向含4个元素的一维数组。 p=a; //将该二维数组的首地址赋给p,也就是a[0]或&a[0][0] p++; //该语句执行过后,也就是p=p+1;p跨过行a[0][]指向了行a[1][] 所以数组指针也称指向一维数组的指针,亦称行指针。 指针数组 定义 int *p[n]; []优先级高,先与p结合成为一个数组,再由int*说明这是一个整型指针数组,它有n个指针类型的数组元素。这里执行p+1是错误的,这样赋值也是错误的:p=a;因为p是个不可知的表示,只存在p[0]、p[1]、p[2]...p[n-1],而且它们分别是指针变量可以用来存放变量地址。但可以这样 *p=a; 这里*p表示指针数组第一个元素的值,a的首地址的值。 如要将二维数组赋给一指针数组: int *p[3]; int a[3][4]; for(i=0;i<3;i++) p[i]=a[i]; 这里int *p[3] 表示一个一维数组内存放着三个指针变量,分别是p[0]、p[1]、p[2] 所以要分别赋值。 这样两者的区别就豁然开朗了,数组指针只是一个指针变量,似乎是C语言里专门用来指向二维数组的,它占有内存中一个指针的存储空间。指针数组是多个指针变量,以数组形式存在内存当中,占有多个指针的存储空间。 还需要说明的一点就是,同时用来指向二维数组时,其引用和用数组名引用都是一样的。 比如要表示数组中i行j列一个元素: *(p[i]+j)、*(*(p+i)+j)、(*(p+i))[j]、p[i][j] 就指向指针的指针,很早以前在说指针的时候说过,但后来发现很多人还是比较难以理解,这一次我们再次仔细说一说指向指针的指针。  先看下面的代码,注意看代码中的注解: #include <iostream>  #include <string>  using namespace std;    void print_char(char* array[],int len);//函数原形声明    void main(void)    {  //-----------------------------段1-----------------------------------------      char *a[]={"abc","cde","fgh"};//字符指针数组      char* *b=a;//定义一个指向指针的指针,并赋予指针数组首地址所指向的第一个字符串的地址也就是abc\0字符串的首地址      cout<<*b<<"|"<<*(b+1)<<"|"<<*(b+2)<<endl;  //-------------------------------------------------------------------------    //-----------------------------段2-----------------------------------------      char* test[]={"abc","cde","fgh"};//注意这里是引号,表示是字符串,以后的地址每加1就是加4位(在32位系统上)      int num=sizeof(test)/sizeof(char*);//计算字符串个数      print_char(test,num);      cin.get();  //-------------------------------------------------------------------------  }    void print_char(char* array[],int len)//当调用的时候传递进来的不是数组,而是字符指针他每加1也就是加上sizeof(char*)的长度  {      for(int i=0;i<len;i++)      {          cout<<*array++<<endl;      }  }   下面我们来仔细说明一下字符指针数组和指向指针的指针,段1中的程序是下面的样子: char *a[]={"abc","cde","fgh"};  char* *b=a;  cout<<*b<<"|"<<*(b+1)<<"|"<<*(b+2)<<endl;   char *a[]定义了一个指针数组,注意不是char[], char[]是不能同时初始化为三个字符的,定义以后的a[]其实内部有三个内存位置,分别存储了abc\0,cde\0,fgh\0,三个字符串的起始地址,而这三个位置的内存地址却不是这三个字符串的起始地址,在这个例子中a[]是存储在栈空间内的,而三个字符串却是存储在静态内存空间内的const区域中的,接下去我们看到了char* *b=a;这里是定义了一个指向指针的指针,如果你写成char *b=a;那么是错误的,因为编译器会返回一个无法将char* *[3]转换给char *的错误,b=a的赋值,实际上是把a的首地址赋给了b,由于b是一个指向指针的指针,程序的输出cout<<*b<<"|"<<*(b+1)<<"|"<<*(b+2)<<endl;   结果是 abc cde fgh   可以看出每一次内存地址的+1操作事实上是一次加sizeof(char*)的操作,我们在32位的系统中sizeof(char*)的长度是4,所以每加1也就是+4,实际上是*a[]内部三个位置的+1,所以*(b+1)的结果自然就是cde了,我们这时候可能会问,为什么输出是cde而不是c一个呢?答案是这样的,在c++中,输出字符指针就是输出字符串,程序会自动在遇到\0后停止.   我们最后分析一下段2中的代码,段2中我们调用了print_array()这个函数,这个函数中形式参数是char *array[]和代码中的char *test[]一样,同为字符指针,当你把参数传递过来的时候,事实上不是把数组内容传递过来,test的首地址传递了进来,由于array是指针,所以在内存中它在栈区,具有变量一样的性质,可以为左值,所以我们输出写成了,cout<<*array++<<endl;当然我们也可以改写为cout<<array[i]<<endl,这里在循环中的每次加1操作和段1代码总的道理是一样的,注意看下面的图!   到这里这两个非常重要的知识点我们都说完了,说归说,要想透彻理解希望读者多动手,多观察,熟能生巧。   下面是内存结构示意图:

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值