对c语言数据类型的扩展
我们在c语言里,基本数据类型 char、unsigned char 、int、short、unsigned short 、 long unsigned long 、float double、long double与C语言相同。扩展了bool类型,对结构体、联合、枚举做了改进。
结构体
1.在c++里我们定义结构体变量,可以省略strcut 关键字
2.C++结构体中可以直接定义函数,谓之成员函数(方法)
话不多说,我们来个实例:
#include <iostream>
#include <cstring>
using namespace std;
int main(void){
struct stu{
int age;
char name[20];
void who(void){
cout <<"我是:" << name << " 我今年:" << age <<endl;
}
};
stu s1;
s1.age = 21;
strcpy(s1.name, "张飞");
s1.who();
return 0;
}
我们看下结果吧:(因为都较为简单的例子,后面就不展示现象了)
联合体
- 类比结构体,咱们在定义联合体变量时,可以忽略union关键字
union XX{……};
XX x;//定义联合体变量直接省略union
2.支持匿名联合
union{ //没有名字
……
};
#include <iostream>
using namespace std;
int main(void){
union{ //匿名联合
int num;
char c[4];
};
num = 0x12345678;
cout << hex << (int)c[0] <<" " << (int)c[1] << endl;
return 0;
}
由结果知,我们这里是小端字节序
枚举
1.C++中定义枚举变量,可以省略enum关键字;
2.C++中枚举是独立的数据类型,不能当做整型数使用。
#include <iostream>
using namespace std;
int main(void){
enum COLOR{RED, GREEN, BLUE};
COLOR c = GREEN;
//c = 2; //error
cout << c << endl;
return 0;
}
布尔
1.C++中布尔(bool)是基本数据类型,专门表示逻辑值;
2.布尔类型的字面值常量:
true 表示逻辑真
false表示逻辑假
3.布尔类型的本质:单字节的整数,使用1表示真,0表示假;
4.任何基本类型都可以被隐式转换为布尔类型。
#include <iostream>
using namespace std;
int main(void){
bool b = true;
cout << b <<endl;
cout <<boolalpha << b <<endl;
b = 3 + 2;
cout <<boolalpha << b <<endl;
return 0;
}
c++中对字符串的处理
1.首先,我们c++兼容c语言里的字符串表示方法和操作函数
2.c++还专门设计了string类型表示字符串
(1)string类型字符串定义
string s; //定义空字符串
string s("hello");
string s = "hello";
string s = string("hello");
(2)字符串拷贝
string s1 = “hello”;
string s2 = s1;
(3)字符串连接
string s1 = “hello”, s2 = “ world”;
string s3 = s1 + s2;//s3:hello world
s1 += s2;//s1:hello world
(4)字符串比较
string s1 = “hello”, s2 = “ world”;
if(s1 == s2){ cout << “false”<< endl; }
if(s1 != s2){ cout << “true”<< endl; }
(5)随机访问
string s = “hello”;
s[0] =“H”; //Hello
(6)获取字符串长度
size_t size();
size_t length();
(7)转换为C风格的字符串
const char* c_str();
(8)字符串交换
void swap(string s1,string s2)
实例:
#include <iostream>
#include <cstdio>
using namespace std;
int main(){
/*定义*/
string s1; //定义空字符串
string s2("aaa");
string s3 = string("bbb");
string s4 = "cccc";
/*字符串的拷贝*/
string s5 = s2; // char *p5 = p2;
cout << "s5 = " << s5 << endl;
/*拼接*/
s5 += s3;
cout << "s5 = " << s5 << endl;
/*字符串比较*/
if(s2 == s3){ //strcmp(.....)
cout << "true" << endl;
}
else
cout << "false" << endl;
/*取字符串长度*/
cout << "s5 length = "<< s5.length() << endl;
/*转换为C风格字符串*/
const char *p = s5.c_str();
printf("%s\n", p);
/*交换*/
swap(s2, s3);
cout << "s2= "<< s2 << " s3= "<< s3<< endl;
return 0;
}
类型转换
类型转换分为隐式转换和显示转换。
写C/C++代码的时候,有时候不可避免的会使用类型转换,良好的编码风格中应该避免隐式转换,隐式转换有时候会产生不易察觉的问题。
隐式类型转换
C++定义了一套标准数据类型转换的规则,在必要时C++会用这套转换规则进行数据类型的转换。这种转换是在程序员不参与的情况下自动进
行的,所以成为隐式类型转换。转换原则:
以下四种情况下会发生转换
(1)多种数据类型的算术表达式中;
int a = 2;
float b = 3.4;
double d = 2.2;
a+b+c;
这里按照上面转换原则,最终三者的结果为double类型
(2)将一种数据类型赋值给另外一种数据类型变量;
int a = 2;
float b = 3.4;
long double d = 2.2;
b = a;
d = a;
(3)函数调用时,若实参表达式与形参的类型不相符;
int Min(int a, int b){
return a<b?a:b;
}
int a = 2;
float b= 3.4;
int x = Min(b, a+3.5);
这里Min函数中,第二个形参会转换为int类型
(4)函数返回时,如果返回表达式的值与函数返回类型不同。
double add(int a, int b){
return a+b;
}
显式类型转换
1.显示类型转换也称为强制类型转换,是指把一种数据类型强制转换为指定的另一种数据类型,也就是我们c语言里的强制转换;
int a = 4;
float c = (float) a; //C风格 c++也支持
float d = float(a); //C++风格 C不支持
2.C++ 提供了更严格的类型转换,可以提供更好的控制转换过程,C++增加了四个强制转换运算符: static_cast, dynamic_cast, const_cast和
reinterpret_cast.
(1)静态类型转换 static_cast
目标类型变量 = static_cast<目标类型> (源类型变量)
用于隐式转换的逆转换,常用于基本数据类型之间的转换、void* 转换 为其它类型的指针
不能用于整型和指针之间的互相转换 , 不能用于不同类型的指针、引用之间的转换 (风险高)
用于自定义类型的转换(向上造型,后面讲)
#include <iostream>
#include <cstdlib>
using namespace std;
int main(void){
int a = 100;
double a1 = (double)a; //c风格
double a2 = double(a);//C++风格
double b = static_cast<double>(a);
void *p = malloc(100);
int *pi = static_cast<int *>(p);
char *pc = static_cast<char *>(p);
//int num = static_cast<int>(p); //error
//pi = static_cast<int *>(pc); //error
return 0;
}
(2)重解释类型转换 reinterpret_cast
目标类型变量 = reinterpret_cast<目标类型> (源类型变量);
用于任意类型指针或引用之间的转换;
指针和整型数之间的转换。
#include <iostream>
#include <cstdlib>
using namespace std;
int main(void){
int a = 100;
double a1 = (double)a; //c风格
double a2 = double(a);//C++风格
double b = static_cast<double>(a);
void *p = malloc(100);
int *pi = static_cast<int *>(p);
char *pc = static_cast<char *>(p);
//int num = static_cast<int>(p); //error
//pi = static_cast<int *>(pc); //error
int num = reinterpret_cast<int>(p);
pi = reinterpret_cast<int *>(pc);
int n = 0x00414243;
char *ps = reinterpret_cast<char *>(&n);
cout << ps << endl;
cout << hex << n << endl ;
return 0;
}
(3)常类型转换 const_cast
目标类型变量 = const_cast<目标类型> (源类型变量);
用于去除指针或引用的常属性
#include <iostream>
using namespace std;
int main(void){
int tmp = 123;
const int *p1 = &tmp; //不能通过指针修改tmp对应的值
//(*p1)++; //error
int *p2 = const_cast<int *>(p1);//去除常属性
*p2 = 10000;
cout << tmp << endl;
return 0;
}
(4)动态类型转换 dynamic_cast
目标类型变量 = dynamic_cast<目标类型> (源类型变量);
主要用于多态中类指针的向下转型,可以检测是否可以转型成功 (后面讲)
引用
c++出现了新的概念:引用。引用是某个对象的别名。
语法格式如下:
类型 &引用名 = 变量名;
#include <iostream>
using namespace std;
int main(void){
int i = 10;
int &ir = i; // 给变量i起了被别名 叫ir
cout << "i = " << i << endl;
cout << "ir = " << ir << endl;
cout << "i的地址: " << &i << endl;
cout << "ir的地址: " << &ir << endl;
return 0;
}
可以看出来ir和i其实是同一块内存。
用途:
1)简化编程, 用指针的场景可以用引用替换 (尽量减少指针的使用)
2)系统开销更小
#include <iostream>
using namespace std;
void swap(int *a, int *b){
int tmp = *a;
*a = *b;
*b = tmp;
}
void swap2(int &a, int &b){
int tmp = a;
a = b;
b = tmp;
}
struct stu{
char name[20];
int age;
int id;
};
void func(struct stu s1){
}
void func2(struct stu &s1){
}
int main(void){
int x = 10;
int y = 20;
//swap(&x, &y);
swap2(x,y);
cout << "x= "<< x << "\t" << "y= " << y << endl;
stu zs;
func(zs);
func2(zs);
return 0;
}
在使用引用时需要注意以下几个问题:
(1).&的位置是灵活的,以下几种定义完全相同;
int& ir = i;
int & ir = i;
int &ir = i;
(2).在变量声明时出现&才是引用运算符(包括函数参数声明和函数返回类型的声明)
int &ir =i;
int &f(int &i1, int &);
(3).引用必须定义时初始化
float f;
float &r1 = f;
float &r2;
r2 = f; //错误
(4).const引用(常引用)。在定义引用时一般为左值(变量)。
左值,是指变量对应的那块内存区域,是可以放在赋值符号左边的值;
右值,是指变量对应的内存区域中存储的数据值,是可以“放在赋值符号右边的值”。
常量、表达式都是右值,例如:
int i = 1;
i = i+10;
i+10 = i;//错误
i=10;
10=i; //错误
可以使用const进行限制,使他成为不允许被修改的常量引用。
int &i = 3; //错误
const int &i = 3;// 正确
int a = 100;
char &c = a; //错误 将a转换char类型,转换结果保存到临时变量中 实际引用临时变量,而临时变量是右值
(5)引用的本质
引用的本质就是指针常量
//int *const x = &m; int *const y= &n
void swap(int &x, int &y){
int tmp = 0;
tmp = x; //tmp = *x;
x = y; // *x = * y;
y = tmp; // *y = tmp
}
int main(void){
int m = 10, n = 20;
swap(m, n);
return 0;
}
好啦!!!今天的分享到这里了,希望各位能好好汲取,多动手,多动手就能更熟悉哦
最后,还是希望大哥大姐们能一键三连!!!拜托啦^ _ ^!