C++中的数据类型

对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;
}

我们看下结果吧:(因为都较为简单的例子,后面就不展示现象了)
在这里插入图片描述

联合体

  1. 类比结构体,咱们在定义联合体变量时,可以忽略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;
}

好啦!!!今天的分享到这里了,希望各位能好好汲取,多动手,多动手就能更熟悉哦
最后,还是希望大哥大姐们能一键三连!!!拜托啦^ _ ^!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值