首页 > 代码库 > 求变量的数据类型,typeid,bool,C和C++的不同,new和delete,C++中的枚举,inline和可变参数模板,auto和函数模板,宽字符
求变量的数据类型,typeid,bool,C和C++的不同,new和delete,C++中的枚举,inline和可变参数模板,auto和函数模板,宽字符
求变量的数据类型,通过函数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");
}
运行结果如下:
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");
}
截图:
3.C++中不同的细节
#include<stdio.h>
#include<iostream>
//C++全局变量没有声明与定义的差别
//静态全局变量也没有声明与定义的差别
//C++是强类型系统,函数返回值必须要有类型
inta;
//inta; 不能重复定义a
staticintb;
//staticint b; 不能重复定义b
//C++编译器 编译的宽泛
//为了修改源代码,后面留下拓展
//占位,占位参数
voidtest(inta,double,int)
{
std::cout << a;
}
voidmain()
{
inta = 3;
//C++检测到右值在存有实体,自动转换为左值
//C语言不会把右值转换为左值
(a = 3) = 4;
intb = 5;
(a >b ?a :b) = 2;
(++a)++;
//register C++编译器做了优化,检测到取地址,就不会把它放到寄存器
//register可以取地址
registerintnum(1);
std::cout << &num <<std::endl;
std::cout << a <<b <<std::endl;
test(1, 2.9, 3);
system("pause");
}
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");
}