https://blog.csdn.net/pipisorry/article/details/25346379
http://blog.csdn.net/pipisorry/article/details/25346379
c++基本数据类型
什么样的数据算是byte类型,int类型,float类型,double类型,long类型?
FLOAT,为数字浮点型,其小数点后面可以跟N个数字
DOUBLE,为双精度数字类型,其小数点后只能有两个数字
int类型
上面提到了在32位机器和64机器中int类型都占用4个字节。后来,查了The C Programming language这本书,里面有一句话是这样的:Each compiler is free to choose appropriate sizes for its own hardware, subject only to the restriction that shorts and ints are at least 16bits, longs are at least 32bits, and short is no longer than int, which is no longer than long.意思大致是编译器可以根据自身硬件来选择合适的大小,但是需要满足约束:short和int型至少为16位,long型至少为32位,并且short型长度不能超过int型,而int型不能超过long型。这即是说各个类型的变量长度是由编译器来决定的,而当前主流的编译器中一般是32位机器和64位机器中int型都是4个字节(例如,GCC)。
下面列举在GCC编译器下32位机器和64位机器各个类型变量所占字节数:
C类型
32 | 64 | |
char | 1 | 1 |
short int | 2 | 2 |
int | 4 | 4 |
long int | 4 | 8 |
long long int | 8 | 8 |
char* | 4 | 8 |
float | 4 | 4 |
double | 8 | 8 |
c语言中int类型为4bytes(64位机上,32位机应该也是),也就是说总是4bytes而不会变,不过不同语言定义的范围不同,如python中是8bytes(64位机)实际对象占用28bytes。
#include <stdio.h>
#include <limits.h>
int main()
{
printf("The value of INT_MAX is %i\n", INT_MAX);
printf("The value of INT_MIN is %i\n", INT_MIN);
printf("An int takes %ld bytes\n", sizeof(int));
return 0;
}
The value of INT_MAX is 2147483647
The value of INT_MIN is -2147483648
An int takes 4 bytes
一字节表示八位,即:1byte = 8 bit;
int: 4byte = 32 bit 有符号signed范围:2^31-1 ~ -2^31即:2147483647 ~ -2147483648 无符号unsigned范围:2^32-1 ~ 0即:4294967295 ~ 0
long: 4 byte = 32 bit 同int型
double: 8 byte = 64 bit 范围:1.79769e+308 ~ 2.22507e-308
long double: 12 byte = 96 bit 范围: 1.18973e+4932 ~ 3.3621e-4932
float: 4 byte = 32 bit 范围: 3.40282e+038 ~ 1.17549e-038
int、unsigned、long、unsigned long 、double的数量级最大都只能表示为10亿,即它们表示十进制的位数不超过10个,即可以保存所有9位整数。而short只是能表示5位。
c++类型转换
1. c++中string到int的转换
1) 在C标准库里面,使用atoi:
#include <cstdlib>
#include <string>std::string text = "152";
int number = std::atoi( text.c_str() );
if (errno == ERANGE) //可能是std::errno
{
//number可能由于过大或过小而不能完全存储
}
else if (errno == ????)
//可能是EINVAL
{
//不能转换成一个数字
}
2) 在C++标准库里面,使用stringstream:(stringstream 可以用于各种数据类型之间的转换)
#include <sstream>
#include <string>std::string text = "152";
int number;
std::stringstream ss;
ss << text;//可以是其他数据类型
ss >> number; //string -> int
if (! ss.good())
{
//错误发生
}ss << number;// int->string
string str = ss.str();
if (! ss.good())
{
//错误发生
}
3) 在Boost库里面,使用lexical_cast:
#include <boost/lexical_cast.hpp>
#include <string>try
{
std::string text = "152";
int number = boost::lexical_cast< int >( text );
}
catch( const boost::bad_lexical_cast & )
{
//转换失败
}
int转换成string
c++中将输入的数字以字符(串)形式输出- #include <iostream>
- #include <sstream>
- #include <string>
- using namespace std;
- void main(){
- int i = 65;
- cout<<char(i)<<endl; //输出‘A' <=>printf("%c\n", i);
- stringstream ss;
- ss<<i;
- string s;
- ss>>s;
- cout<<s<<endl; //输出”65“
- char *c = new char;
- itoa(65, c, 10);
- cout<<c<<endl; //输出”65“
- //cout<<strcmp(c, "65")<<endl;
- }
2.string 转 CString
CString.format(”%s”, string.c_str());用c_str()确实比data()要好;
3.char 转 CString
CString.format(”%s”, char*);4.char 转 string
string s(char *);只能初始化,在不是初始化的地方最好还是用assign().
5.string 转 char *
char *p = string.c_str();6.CString 转 string
string s(CString.GetBuffer());GetBuffer()后一定要ReleaseBuffer(),否则就没有释放缓冲区所占的空间.
7.字符串的内容转换为字符数组和C—string
(1) data(),返回没有”\0“的字符串数组(2) c_str(),返回有”\0“的字符串数组
(3) copy()
8.CString与int、char*、char[100]之间的转换
(1) CString互转int
将字符转换为整数,可以使用atoi、_atoi64或atol。而将数字转换为CString变量,可以使用CString的Format函数。如
CString s;
int i = 64;
s.Format(”%d”, i)
Format函数的功能很强,值得你研究一下。
void CStrDlg::OnButton1()
{
CString
ss=”1212.12″;
int temp=atoi(ss);
CString aa;
aa.Format(”%d”,temp);
AfxMessageBox(”var is ” + aa);
}
(2) CString互转char*
///char * TO cstring
CString strtest;
char * charpoint;
charpoint=”give string a value”; //?
strtest=charpoint;
///cstring TO char *
charpoint=strtest.GetBuffer(strtest.GetLength());
(3) char *转成CString
标准C里没有string,char *==char []==string, 可以用CString.Format(”%s”,char *)这个方法来将char *转成CString。
要把CString转成char *,用操作符(LPCSTR)CString就可以了。
CString转换 char[100]
char a[100];
CString str(”aaaaaa”);
strncpy(a,(LPCTSTR)str,sizeof(a));
static_cast类型转换
static_cast < type-id > ( expression )
注意:static_cast不能转换掉expression的const、volatile、或者__unaligned属性。
1
2
3
|
int
i;
float
f = 166.71;
i =
static_cast
<
int
>(f);
|
1
2
3
|
int
i;
char
*p =
"This is an example."
;
i =
reinterpret_cast
<
int
>(p);
|
虽然const_cast是用来去除变量的const限定,但是static_cast却不是用来去除变量的static引用。其实这是很容易理解的,static决定的是一个变量的作用域和生命周期,比如:在一个文件中将变量定义为static,则说明这个变量只能在本Package中使用;在方法中定义一个static变量,该变量在程序开始存在直到程序结束;类中定义一个static成员,该成员随类的第一个对象出现时出现,并且可以被该类的所有对象所使用。对static限定的改变必然会造成范围性的影响,而const限定的只是变量或对象自身。但无论是哪一个限定,它们都是在变量一出生(完成编译的时候)就决定了变量的特性,所以实际上都是不容许改变的。这点在const_cast那部分就已经有体现出来。
static_cast和reinterpret_cast一样,在面对const的时候都无能为力:两者都不能去除const限定。两者也存在的很多的不同,比如static_cast不仅可以用在指针和引用上,还可以用在基础数据和对象上;reinterpret_cast可以用在"没有关系"的类型之间,而用static_cast来处理的转换就需要两者具有"一定的关系"了。reinterpret_cast可以在任意指针之间进行互相转换,即使这些指针所指的内容是毫无关系的,也就是说一下语句,编译器是不会报错的,但是对于程序来说也是毫无意义可言的,只会造成程序崩溃
unsignedshort Hash( void *p ) {
unsignedlong val = reinterpret_cast<unsignedlong>( p );
return ( unsigned short )( val ^ (val >> 16));
}
int main() {
typedefunsignedshort (*FuncPointer)( void *) ;
FuncPointer fp = Hash; //right,this is what we want
int a[10];constint* ch = a; //right, array is just like pointer
char chArray[4] = { 'a','b','c','d'};
fp = reinterpret_cast<FuncPointer> (ch); //no error, but does not make sense
ch = reinterpret_cast<int*> (chArray); //no error
cout <<hex<< *ch; //output: 64636261 //it really reinterpret the pointer
}
而以上转换,都是static_cast所不能完成的任务,也就是说把上边程序里所有的reinterpret_cast换成static_cast的话,就会立即得到编译错误,因为目标指针和原始指针之间不存在"关系"
从上边的程序,也就一下子看出来了reinterpret_cast和static_cast之间最本质的区别。
但是从基类到子类的转换,用static_cast并不是安全的,具体的问题会在dynamic_cast一篇阐述。
在指针和引用方便,似乎也只有继承关系是可以被static_cast接受的,其他情况的指针和引用转换都会被static_cast直接扔出编译错误,而这层关系上的转换又几乎都可以被dynamic_cast所代替。这样看起来static_cast运算符的作用就太小了。
实际上static_cast真正用处并不在指针和引用上,而在基础类型和对象的转换上 。 而基于基础类型和对象的转换都是其他三个转换运算符所办不到的
from: http://blog.csdn.net/pipisorry/article/details/25346379
ref:
https://blog.csdn.net/weixin_41376979/article/details/88336748
c/c++基础篇之数据类型转换
1. 常见的单类基本类型转换
(1)强制类型转换
如: int a=(int)(9.87) 结果a=9
char c=(char)(97) 结果为c=’a’
特别注意的是,在c++11中,增加了auto关键字,转换类型相对智能化
auto c=(int)(9.87) 结果c=9
(2)string与char * ,char arr[]
String----const char *
c_str()生成一个constchar*指针,指向以空字符终止的数组。
例1:const char *c; string s=”1234”; c=s.c_str();cout<<c; 输出结果为1234
例2:string str=”lol”; char * ptr=new char[str.length()+1]; strcat(ptr,str)
String---char s[]
可以利用strcpy函数(需先转换成constchar *)或者利用循环对字符数组逐一赋值
例:string s(‘test’);char str[10];
strcpy(str,s.c_str())
for(inti=0;i<s.length();i++) {str[i]=s[i]}
char s[]与char *------string
可以直接赋值 char *ptr; char arr[]; string s1=ptr; string s2=arr;
(3)char *与int
头文件:#include<stdlib.h>
atoi() 函数用来将字符串转换成整数(int),其原型为:intatoi (const char * str);
例:char *numchars="1234"; int num=atoi(numchars); 结果为1234
itoa()函数用于整数到字符串的转换,其原型为:char*itoa(int value, char *string, int radix);
例:int num=1234; int radix=8; char res[20]; itoa(num,res,radix);
printf("%d(10)=%s(%d)\n",num,res,radix);//输出1234(10)=2322(8) 这里radix指的是进制
同时c++还提供标准库函数有:long int atol ( const char * str ); double atof (constchar* str);
stof()、strtod()、strtol()、strtoul()、atoll()、strtof()、strtold()、strtoll()、strtoull(),详情可在网上查阅。
(4)string与int
利用stoi()直接转换
例:string s=”1234”;int b=stoi(s) 结果为1234
利用atoi()间接转换
例:string s=”1234”;int b=atoi(s.c_str()) 结果为1234
(5)sprintf作用是将printf的输出结果保存在字符串数组中。
2.一些特殊的数据类型转换
(1)type b= static_cast<type>(a) 将type1 a的类型转化为type2 b的类型;
使用范围:完成编译器认可的隐式类型转换,但不支持指针与常见的int、float等类型转换。
①基本数据类型之间的转换,如int->double;
int a = 6;
double b = static_cast<int>(a);
②派生体系中向上转型:将派生类指针或引用转化为基类指针或引用(向上转型);
class base{ …. }
class derived : public base{ …. }
base *b;
derived *d = new derived();
b = static_cast<base *>(d);
(2) dynamic_cast
功能:执行派生类指针或引用与基类指针或引用之间的转换。
格式:
①其他三种都是编译时完成的,dynamic_cast是运行时处理的,运行时要进行运行时类型检查;
②不能用于内置的基本数据类型的强制转换。 dynamic_cast转换如果成功的话返回的是指向类的指针或引用,转换失败的话则会返回NULL。
③使用dynamic_cast进行转换的,基类中一定要有虚函数,否则编译不通过。
需要检测有虚函数的原因:类中存在虚函数,就说明它有想要让基类指针或引用指向派生类对象的情况,此时转换才有意义。
这是由于运行时类型检查需要运行时类型信息,而这个信息存储在类的虚函数表(关于虚函数表的概念)中,只有定义了虚函数的类才有虚函数表。
④在类的转换时,在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的。在进行下行转换时,dynamic_cast具有类型检查的功能,比 static_cast更安全。向上转换即为指向子类对象的向下转换,即将父类指针转化子类指针。向下转换的成功与否还与将要转换的类型有关,即要转换的指针指向的对象的实际类型与转换以后的对象类型一定要相同,否则转换失败。可以实现向上转型和向下转型,前提是必须使用public或protected继承;
例子:
向上转型:
class base{ … };
class derived : public base{ … };
int main()
{
base *pb;
derived *pd = new derived();
pb = dynamic_cast<base *>(pd);
return 0;
}
向下转型:
class base{ virtualvoid func(){} };
class derived : public base{ void func(){} };
int main()
{ base*pb = new base();
derived *pd = dynamic_cast<derived*>(pb);//向下转型
return 0; }
(3) const_cast
只能对指针或者引用去除或者添加const属性,对于变量直接类型不能使用const_cast;不能用于不同类型之间的转换,只能改变同种类型的const属性。
如:
const int a= 0; int b = const_cast<int>(a);//不对的
const int *pi = &a; int * pii = const_cast<int *>pi;//去除指针中的常量性,也可以添加指针的常量性;
const_cast的用法:const_cast操作不能在不同的种类间转换。相反,它仅仅把一个它作用的表达式转换成常量。它可以使一个本来不是const类型的数据转换成const类型的,或者把const属性去掉。
(4)reinterpret_cast
interpret是解释的意思,reinterpret即为重新解释,此标识符的意思即为数据的二进制形式重新解释,但是不改变其值.有着和C风格的强制转换同样的能力。它可以转化任何内置的数据类型为其他任何的数据类型,也可以转化任何指针类型为其他的类型。它甚至可以转化内置的数据类型为指针,无须考虑类型安全或者常量的情形。不到万不得已绝对不用。
https://blog.csdn.net/weixin_41376979/article/details/88336748
C++中数字与字符的转换(通过简单输入输出流实现)