- 求变量的数据类型,通过函数typeid(变量名).name();获得变量的数据类型。
案例如下:
#include<iostream>
#include<stdlib.h>
voidmain()
{
doubledb
= 10.9;
double
*pdb = &db;
autonum
=pdb;
//通过typeid的方式获得数据类型
std::cout
<< typeid(db).name()
<< std::endl;
std::cout
<< typeid(num).name()
<< std::endl;
std::cout
<< typeid(pdb).name()
<< std::endl;
//typeid(db).name() db2
//decltype用于查询表达式的数据类型(Declared
Type)
decltype(db)numA(10.8);
std::cout
<< sizeof(numA)
<< " " <<numA
<<std::endl;
system("pause");
}
运行结果如下:
注意:如果是在QT中运行(要加上C++11的配置,在.pro中添加:
CONFIG += C++11),代码如下:
#include<iostream> #include<stdlib.h> #include<typeinfo> /* *求变量的数据类型通过函数typeid(变量名).name()获得变量的的数据类型 */ usingnamespacestd;
intmain() { doubledb=10.9; double*pdb=&db; autonum=pdb; //通过typeid的方式获得数据类型 std::cout<<typeid(db).name()<<std::endl; std::cout<<typeid(num).name()<<std::endl; std::cout<<typeid(pdb).name()<<std::endl;
//typeid(db).name()db2 //decltype用于查询表达是的数据类型(DeclaredType) decltype(db)numA(10.8); std::cout<<sizeof(numA)<<""<<numA<<std::endl;
return0; }
运行结果: |
2.bool类型
#include<iostream>
#include<stdlib.h>
voidmain()
{
boolb1
= (1 && 1) || 2 || (-1 && 0);
std::cout
<< typeid(b1).name()
<< std::endl;
std::cout
<< b1 <<std::endl;
decltype(b1)bt(1
+ 2 * 3 - 4 && 3 + 2 || -1);
std::cout
<< typeid(bt).name()
<< std::endl;
std::cout
<< bt <<std::endl;
system("pause");
}
截图:
在QT中要加上#include<typeinfo>
运行结果是:
3.C++中不同的细节
#include<stdio.h>
#include<iostream>
//C++全局变量没有声明与定义的差别
//静态全局变量也没有声明与定义的差别
//C++是强类型系统,函数返回值必须要有类型
inta;
//inta;
不能重复定义a
staticintb;
//staticintb;
不能重复定义b
//C++编译器编译的宽泛
//为了修改源代码,后面留下拓展
//占位,占位参数
voidtest(inta,double,int)
{
std::cout<<a;
}
intmain()
{
inta=3;
//C++检测到右值在存有实体,自动转换为左值
//C语言不会把右值转换为左值
(a=3)=4;
intb=5;
(a>b?a:b)=2;
(++a)++;
//registerC++编译器做了优化,检测到取地址,就不会把它放到寄存器
//register可以取地址
registerintnum(1);
std::cout<<&num<<std::endl;
std::cout<<a<<""<<b<<std::endl;
test(1,2.9,3);
return0;
}
QT中的运行结果是:
4.new和delete
A:用了delete之后,最好使用使用p
=NULL;
#include<stdio.h>
#include<stdlib.h>
voidmain()
{
int
*p =newint;
deletep;//防止重复删除
p
=NULL;
deletep;
system("pause");
}
delete只能delete一次,案例如下:
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
voidmain()
{
intnum
= 10;//栈上
int
*p =newint;//堆上
*p
= 5;
std::cout
<< *p <<"
" <<p
<<std::endl;
deletep;
deletep;//只能释放一次
std::cout
<< p <<std::endl;
system("pause");
}
错误截图如下:
修改后的状态
delete删除数组元素的时候,要加上[],案例如下:
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
voidmain()
{
//int num[110]
int
*p =newint[10];
std::cout
<< p <<std::endl;
//下面定义int
i = 0的循环方式C99标准支持
for
(inti
= 0;i < 10;i++)
{
p[i]
= i;
std::cout
<< p[i]
<< std::endl;
}
delete[]p;//删除数组的空间
std::cout
<< p <<std::endl;
system("pause");
}
截图如下:
删除对象数组的案例如下:
#include<iostream>
#include<stdlib.h>
classtansheng
{
int
*p;
intlength;
public:
tansheng()//构建的时候初始化
{
std::cout
<< "谭胜被创建"
<< std::endl;
}
~tansheng()//删除的时候释放内存
{
std::cout
<< "谭胜被销毁"
<< std::endl;
}
};
voidmain()
{
tansheng
*p =newtansheng;
deletep;//基本数据类型,delete,复杂类型必须加上[]
system("pause");
}
截图如下:
#include<iostream>
#include<stdlib.h>
classtansheng
{
public:
staticintjishuqi;//静态
int
*p;
intlength;
public:
tansheng()//构建的时候初始化
{
std::cout
<< "谭胜被创建"
<< std::endl;
}
~tansheng()//删除的时候放内存
{
std::cout
<< "谭胜被销毁"
<< std::endl;
}
staticvoid
* operator new(size_tsize)
{
jishuqi
+= 1;
std::cout
<< "对象被创建"
<< std::endl;
tansheng
*ptemp = ::newtansheng;//劫持
returnptemp;
}
staticvoid
operator delete(void *p)
{
jishuqi
-= 1;
std::cout
<< "对象被销毁"
<< std::endl;
::deletep;//
::全局
}
};
inttansheng::jishuqi
= 0;
//类的内部的new没有完成分配内存的动作
//通往全局的new中间做了一个劫持
//空类占一个字节,表示自己存在
//类的对象,数据是独立,代码是共享的
//没有分配内存,构造函数无意义
classMyClass
{
intnum;
public:
MyClass();
~MyClass();
private:
};
MyClass::~MyClass()
{
}
voidmain()
{
tansheng
*p1 =newtansheng;
tansheng
*p2 =newtansheng;
tansheng
*p3 =newtansheng;
tansheng
*p4 =newtansheng;
std::cout
<< p1 <<p2
<<std::endl;
deletep1;
deletep2;
std::cout
<< tansheng::jishuqi
<< std::endl;
std::cout
<< "myclass size" <<sizeof(MyClass)
<< std::endl;
int
*p =newint;
system("pause");
}
结果如下:
5.枚举类型
#include<iostream>
enumcolor
:char{red
='A',yellow,green,white
};
voidmain()
{
colormycolor
=red;
//mycolor = 'A'; //确保在枚举的范围的之内不出错
mycolor
=color::white;//新语法
colormycolor1(red);
colormycolor2(color::red);
printf("%d,%c\n",red,red);
printf("%d,%c\n",yellow,yellow);
system("pause");
}
6.两个大数的字符串求乘
#define_CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<stdlib.h>
#include<string.h>
//除了数据还有函数
structbigdatacom
{
protected://内部私有
chardataa[100];
chardatab[100];
public://共有公开
voidinit(constchar
*str1,constchar
*str2)
{
std::cout
<< typeid(*this).name()
<< std::endl;
strcpy(this->dataa,str1);
strcpy(this->datab,str2);
}
char
*getbigdata()
{
intlengtha
=strlen(dataa);
intlengthb
=strlen(datab);
//两个数相乘,乘得到的位数不可能大于两个数的位数之和
int
*pres = (int
*)malloc(sizeof(int)*(lengtha
+ lengthb));
//初始化
memset(pres,
0, sizeof(int)*(lengtha
+ lengthb));
//累乘
for
(inti
= 0;i <lengtha;i++)
{
for
(intj
= 0;j <lengthb;j++)
{
//其中字符1-->9减去‘0’得到的恰巧是整型值
pres[i
+ j] += (dataa[i]
- '0')*(datab[j]
- '0');
}
}
//进位
for
(inti
=lengtha +lengthb
- 1;i >= 0;i--)
{
if
(pres[i]
>= 10)//进位
{
pres[i
- 1] += pres[i]
/ 10;//进位
pres[i]
%= 10;//取出个位数
}
}
inti
= 0;
while
(pres[i]
== 0)
{
i++;//恰好不为0的位置
}
char
*lastres = (char*)malloc(sizeof(char)*(lengtha
+ lengthb));
intj;
for
(j = 0;j
<lengtha +lengthb;j++,i++)
{
lastres[j]
= pres[i]
+ '0';
}
lastres[j]
= '\0';
returnlastres;
}
};
structmyclass
:publicbigdatacom //继承
{
voidcoutstr() //新增
{
std::cout
<< this->dataa
<< this->datab
<< std::endl;
}
};
voidmain()
{
myclass class1;
class1.init("12345","1000");
std::cout
<< class1.getbigdata()
<< std::endl;
class1.coutstr();
system("pause");
}
voidmain1()
{
bigdatacombig1;//C++结构体可要可不要struct
big1.init("123123","456456");
std::cout
<< big1.getbigdata()
<< std::endl;
system("pause");
}
7.inline只是对于编译器的建议
一般情况下,我们队内联函数做如下的限制
A:不能有递归
B:不能包含静态数据
C:不能包含循环
D:不能包含switch和goto语句
E:不能包含数组
若一个内联函数定义不满足以上限制,则编译系统把它当做普通函数对待。
案例说明:
#include<stdlib.h>
#include<iostream>
//替换
#defineGETX3(N)N*N*N
//1+2*1+2*1+2
//函数
//inline只是对于编译器的建议
////一般情况下,我们对内联函数做如下的限制:
//(1)不能有递归
//(2)不能包含静态数据
//(3)不能包含循环
//(4)不能包含switch和goto语句
//(5)不能包含数组
//若一个内联函数定义不满足以上限制,则编译系统把它当作普通函数对待。
inlineint getX3(intx);//内联函数,内部展开
inlineint getX3(intx)//类型安全
{
returnx*x*x;
}
template <classT>
inlineTgetX2(Tx)//C++类型不匹配出错,不是单纯的替换
{
returnx*x;
}
voidmain()
{
std::cout
<< GETX3(1 + 2) <<std::endl;
std::cout
<< GETX3((1 + 2)) <<std::endl;
std::cout
<< GETX3((2.0 + 2)) <<std::endl;
system("pause");
}
运行结果:
8.函数模板和可变参数
#define_CRT_SECURE_NO_WARNINGS
#include<stdlib.h>
#include<iostream>
#include<cstdarg>
//函数模板,可变参数
//参数至少要有一个模板类型
template<typenameNT>
NTsum(intcount,NTdata1
...)//累加
{
va_listarg_ptr; //参数列表的指针
va_start(arg_ptr,count);//限定从count开始,限定多少个参数
NTsumres(0);
for
(inti
= 0;i <count;i++)
{
sumres
+=va_arg(arg_ptr,NT);
}
va_end(arg_ptr); //结束
returnsumres;
}
//T通用数据类型
template<typenameT>
TMAX(T*p,constintn)
{
Tmaxdata(p[0]);
for
(inti
= 1;i <n;i++)
{
if
(maxdata <p[i])
{
maxdata
=p[i];
}
}
returnmaxdata;
}
intgetmax(int
*p,intn)
{
intmax(0);
max
=p[0]; //假设第一个数位最大
for
(inti
= 1;i < 10;i++)
{
//确保max>=
p[i]
if
(max <p[i])
{
max
=p[i];
}
}
returnmax;
}
doublegetmax(double
*p,intn)
{
doublemax(0);
max
=p[0];//假定第一个数位最大
for
(inti
= 1;i < 10;i++)
{
if
(max <p[i])//确保max>=p[i]
{
max
=p[i];//
}
}
returnmax;
}
voidmain()
{
std::cout
<< sum(5, 1, 2, 3, 4, 5) <<std::endl;
std::cout
<< sum(6, 1, 2, 3, 4, 5, 6) <<std::endl;
std::cout
<< sum(7, 1, 2, 3, 4, 5, 6, 7) <<std::endl;
std::cout
<< sum(7, 1.1, 2.1, 3.1, 4.1, 5.1, 6.1, 7.1) <<std::endl;
std::cout
<< sum(6, 1.1, 2.1, 3.1, 4.1, 5.1, 6.1) <<std::endl;
std::cout
<< "-----------------" <<std::endl;
doublea[10]
= { 2, 3, 4, 98, 77, 999.1, 87, 123, 0, 12 };
int b[10]
= { 1, 2, 3, 4,15, 6, 7, 8, 9, 10 };
std::cout
<< MAX(a,
10) << std::endl;
std::cout
<< MAX(b,
10) << std::endl;
system("pause");
}
9.auto与函数模板
A:函数参数不允许使用自动变量
B:auto结合模板函数的案例如下:
#include<stdlib.h>
#include<iostream>
//自动数据类型,根据实际推导出类型
template <classT1,classT2> //根据类型获取类型
autoget(T1data,T2bigdata)->decltype(data
*bigdata)
{
returndata
*bigdata;
}
voidmain()
{
std::cout
<< typeid(get(12.0,'A')).name()
<< std::endl;
std::cout
<< get(12.0,'A')
<<std::endl;
std::cout
<< typeid(get(12,'A')).name()
<< std::endl;
std::cout
<< get(12,'A')
<<std::endl;
system("pause");
}
运行结果如下:
10.宽字符
#include<iostream>
#include<stdlib.h>
#include<locale>
voidmain()
{
setlocale(LC_ALL,"chs");//设置本地化
wchar_t
*p1 = L"123456123123qweqeqe";
std::wcout
<< p1 <<std::endl;
wchar_t
*p2 = L"北京123456";
std::wcout
<< p2 <<std::endl;
system("pause");
}