- 求变量的数据类型,通过函数typeid(变量名).name();获得变量的数据类型。
案例如下:
#include
<iostream>
#include
<stdlib.h>
void
main()
{
double
db = 10.9;
double *pdb
= &db;
auto
num =
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>
void
main()
{
bool
b1 = (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++是强类型系统,函数返回值必须要有类型
int
a;
//inta;
不能重复定义a
static
int
b;
//staticint b;
不能重复定义b
//C++编译器 编译的宽泛
//为了修改源代码,后面留下拓展
//占位,占位参数
void
test(int
a,
double,
int)
{
std::cout
<< a;
}
void
main()
{
int
a = 3;
//C++检测到右值在存有实体,自动转换为左值
//C语言不会把右值转换为左值
(a = 3) = 4;
int
b = 5;
(a >
b ?
a :
b) = 2;
(++a)++;
//register C++编译器做了优化,检测到取地址,就不会把它放到寄存器
//register
可以取地址
register
int
num(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>
void
main()
{
int *p
= new
int;
delete
p;
//防止重复删除
p =
NULL;
delete
p;
system("pause");
}
delete只能delete一次,案例如下:
#include
<stdio.h>
#include
<stdlib.h>
#include
<iostream>
void
main()
{
int
num = 10;//栈上
int *p
= new
int;//堆上
*p = 5;
std::cout
<< *p <<
" " <<
p <<
std::endl;
delete
p;
delete
p;//只能释放一次
std::cout
<< p <<
std::endl;
system("pause");
}
错误截图如下:
修改后的状态
delete删除数组元素的时候,要加上[],案例如下:
#include
<stdio.h>
#include
<stdlib.h>
#include
<iostream>
void
main()
{
//int num[110]
int *p
= new
int[10];
std::cout
<< p <<
std::endl;
//下面定义int i = 0的循环方式C99标准支持
for (int
i = 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>
class
tansheng
{
int *p;
int
length;
public:
tansheng()//构建的时候初始化
{
std::cout
<< "谭胜被创建"
<< std::endl;
}
~tansheng()//删除的时候释放内存
{
std::cout
<< "谭胜被销毁"
<< std::endl;
}
};
void
main()
{
tansheng *p
= new
tansheng;
delete
p;//基本数据类型,delete,复杂类型必须加上[]
system("pause");
}
截图如下:
#include
<iostream>
#include
<stdlib.h>
class
tansheng
{
public:
static
int
jishuqi;//静态
int *p;
int
length;
public:
tansheng()
//构建的时候初始化
{
std::cout
<< "谭胜被创建"
<< std::endl;
}
~tansheng()
//删除的时候放内存
{
std::cout
<< "谭胜被销毁"
<< std::endl;
}
static
void * operator new(size_t
size)
{
jishuqi += 1;
std::cout
<< "对象被创建"
<< std::endl;
tansheng *ptemp
= ::new
tansheng;//劫持
return
ptemp;
}
static
void operator delete(void
*p)
{
jishuqi -= 1;
std::cout
<< "对象被销毁"
<< std::endl;
::delete
p;//
::全局
}
};
int
tansheng::jishuqi
= 0;
//类的内部的new没有完成分配内存的动作
//通往全局的new中间做了一个劫持
//空类占一个字节,表示自己存在
//类的对象,数据是独立,代码是共享的
//没有分配内存,构造函数无意义
class
MyClass
{
int
num;
public:
MyClass();
~MyClass();
private:
};
MyClass::~MyClass()
{
}
void
main()
{
tansheng *p1
= new
tansheng;
tansheng *p2
= new
tansheng;
tansheng *p3
= new
tansheng;
tansheng *p4
= new
tansheng;
std::cout
<< p1 <<
p2 <<
std::endl;
delete
p1;
delete
p2;
std::cout
<< tansheng::jishuqi
<< std::endl;
std::cout
<< "myclass size" <<
sizeof(MyClass)
<< std::endl;
int *p
= new
int;
system("pause");
}
结果如下:
5.枚举类型
#include
<iostream>
enum
color :char{
red =
‘A‘,
yellow,
green,
white };
void
main()
{
color
mycolor =
red;
//mycolor = ‘A‘; //确保在枚举的范围的之内不出错
mycolor =
color::white;//新语法
color
mycolor1(red);
color
mycolor2(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>
//除了数据还有函数
struct
bigdatacom
{
protected://内部私有
char
dataa[100];
char
datab[100];
public://共有公开
void
init(const
char *str1,
const
char *str2)
{
std::cout
<< typeid(*this).name()
<< std::endl;
strcpy(this->dataa,
str1);
strcpy(this->datab,
str2);
}
char *getbigdata()
{
int
lengtha =
strlen(dataa);
int
lengthb =
strlen(datab);
//两个数相乘,乘得到的位数不可能大于两个数的位数之和
int *pres
= (int *)malloc(sizeof(int)*(lengtha
+ lengthb));
//初始化
memset(pres,
0, sizeof(int)*(lengtha
+ lengthb));
//累乘
for (int
i = 0;
i <
lengtha;
i++)
{
for (int
j = 0;
j <
lengthb;
j++)
{
//其中字符1-->9减去‘0’得到的恰巧是整型值
pres[i
+ j] += (dataa[i]
- ‘0‘)*(datab[j]
- ‘0‘);
}
}
//进位
for (int
i =
lengtha +
lengthb - 1;
i >= 0;
i--)
{
if (pres[i]
>= 10)//进位
{
pres[i
- 1] += pres[i]
/ 10;//进位
pres[i]
%= 10;//取出个位数
}
}
int
i = 0;
while (pres[i]
== 0)
{
i++;//恰好不为0的位置
}
char *lastres
= (char*)malloc(sizeof(char)*(lengtha
+ lengthb));
int
j;
for (j
= 0; j <
lengtha +
lengthb;
j++,
i++)
{
lastres[j]
= pres[i]
+ ‘0‘;
}
lastres[j]
= ‘\0‘;
return
lastres;
}
};
struct
myclass :public
bigdatacom
//继承
{
void
coutstr()
//新增
{
std::cout
<< this->dataa
<< this->datab
<< std::endl;
}
};
void
main()
{
myclass
class1;
class1.init("12345",
"1000");
std::cout
<< class1.getbigdata()
<< std::endl;
class1.coutstr();
system("pause");
}
void
main1()
{
bigdatacom
big1;//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>
//替换
#define
GETX3(N)
N*N*N
//1+2*1+2*1+2
//函数
//inline只是对于编译器的建议
////一般情况下,我们对内联函数做如下的限制:
//(1)不能有递归
//(2)不能包含静态数据
//(3)不能包含循环
//(4)不能包含switch和goto语句
//(5)不能包含数组
//若一个内联函数定义不满足以上限制,则编译系统把它当作普通函数对待。
inline
int
getX3(int
x);//内联函数,内部展开
inline
int
getX3(int
x)//类型安全
{
return
x*x*x;
}
template <class
T>
inline
T
getX2(T
x)//C++类型不匹配出错,不是单纯的替换
{
return
x*x;
}
void
main()
{
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<typename
NT>
NT
sum(int
count,
NT
data1 ...)
//累加
{
va_list
arg_ptr;
//参数列表的指针
va_start(arg_ptr,
count);//限定从count开始,限定多少个参数
NT
sumres(0);
for (int
i = 0;
i <
count;i++)
{
sumres +=
va_arg(arg_ptr,
NT);
}
va_end(arg_ptr);
//结束
return
sumres;
}
//T通用数据类型
template<typename
T>
T
MAX(T*p,
const
int
n)
{
T
maxdata(p[0]);
for (int
i = 1;
i <
n;i++)
{
if (maxdata
< p[i])
{
maxdata =
p[i];
}
}
return
maxdata;
}
int
getmax(int
*p,
int
n)
{
int
max(0);
max =
p[0];
//假设第一个数位最大
for (int
i = 1;
i < 10;i++)
{
//确保max>= p[i]
if (max
< p[i])
{
max =
p[i];
}
}
return
max;
}
double
getmax(double
*p,
int
n)
{
double
max(0);
max =
p[0];//假定第一个数位最大
for (int
i = 1;
i < 10;
i++)
{
if (max
< p[i])//确保max>=p[i]
{
max =
p[i];//
}
}
return
max;
}
void
main()
{
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;
double
a[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 <
class
T1,class
T2>
//根据类型获取类型
auto
get(T1
data,
T2
bigdata)->decltype(data
*bigdata)
{
return
data *
bigdata;
}
void
main()
{
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>
void
main()
{
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");
}
求变量的数据类型,typeid,bool,C和C++的不同,new和delete,C++中的枚举,inline和可变参数模板,auto和函数模板,宽字符