从C到C++语法过度1

从C到C++语法过度1

文章目录

  • 从C到C++语法过度1
    • [1. 字符串string](#1. 字符串string)
    • [2. 引用](#2. 引用)
    • [3. 类型转换](#3. 类型转换)
      • [3.1 新式转换 `const_cast`](#3.1 新式转换 const_cast)
      • [3.2 新式转换 `static_cast`](#3.2 新式转换 static_cast)
    • [4. 关键字auto](#4. 关键字auto)

1. 字符串string

C语言从本质上来说,是没有字符串这种类型的,在C语言中如果要表达字符串,只能间接地借助于字符指针或者字符数组来表达,很明显这是由于C语言的诞生年代过于久远而导致的一种设计缺陷。

在C++中,字符串就跟整型、浮点型数据一样,是系统原生支持的一种基本数据类型:

c++ 复制代码
string s;

有了字符串string这种类型之后,很多对字符串的操作就变得非常简单而直观了,C++对string类型的支持包括:

c++ 复制代码
// 字符串的赋值
string s1 = "abdc";

// 字符串的复制
string s2;
s2 = s1;

// 字符串的拼接
string s3;
s3  = "xyz" + s1;
s3 += "123";

// 字符串的比对
if(s1 == "abcd")
    cout << s1 << " == abcd" << endl;
else if(s1 > "abcd")
    cout << s1 << " > abcd" << endl;
else if(s1 < "abcd")
    cout << s1 << " < abcd" << endl;

// 字符串中的元素引用
s1[1] = 'B'; // 将s1修改为"aBcd"

当然,字符串 string 类型数据的操作接口远远不止以上那些,基本上我们能想到的任何对字符串的操作,这个类型本身都支持的。

2. 引用

概念:给一个已有对象取一个别名

语法:

c++ 复制代码
int   a = 100;
int &ra = a; // 从此之后,a 跟 ra 是同一个变量,代表同一块内存
c++ 复制代码
// 以下代码具有等价的作用
 a = 200;
ra = 200;

注意点:

  • 引用必须在定义的同时赋值,不可单独定义引用,例如 int &r; 是错误的。
  • 引用一方面提高了数据传输的效率,另一方面简化了数据表达的样式(跟指针相比)

3. 类型转换

对于数据类型转换,C++完全兼容C语言的类型转换语法,同时又新加了更合理的书写形式和更安全的新式类型转换,如下面所示:

旧式转换

c++ 复制代码
(char)a; // C语言风格类型转换
char(a); // C++风格类型转换

新式转换

c++ 复制代码
const_cast<char *>(a);
static_cast<char *>(a);
dynamic_cast<char *>(a);

新式转换是C++的全新特性,这几个转换关键字含义如下:

  • const_cast : 专用于去除指针或引用的 const 属性
  • static_cast : 与旧式转换相近,但提供了更易于查找的语法,并能有效识别不兼容类型。
  • dynamic_cast : 专用于类类型的上下代际间的转换

3.1 新式转换 const_cast

首先,先要明确 const_cast 的使用规范:

  • const_cast 旨在去除标识符的cv限定属性(即 constvolatile
  • const_cast 只能作用于指针或引用类型

以下是 const_cast 的具体用法:

处理 const 型引用

c++ 复制代码
int main()
{
        int   i = 6; // 普通整型变量
    const int &ri = i; // const型引用,不可修改

    // ×: 以下语句错误
    ri = 8;

    // √: 去除 const 特性后,可以赋值
    const_cast<int &>(ri) = 8;
}

处理常目标指针

c++ 复制代码
int main()
{
          int  i = 6;
	const int *p = &i; // 常目标指针p,不可修改目标

    // ×: 试图修改常指针的目标,错误!
    *p = 8;

	// √: 去除 const 特性后,可以修改其目标
	*(const_cast<int *>(p)) = 8;



    // ×: 试图扩大权限,错误!
    int *k = p;
        
	// √: 去除 const 特性后,可赋值给普通指针 k 
	int *k = const_cast<int *>(p);
}

注意,虽然 const_cast 可以将常目标指针的 const 属性剔除掉,但它不能剔除普通变量和常指针本身的 const 属性。例如:

c++ 复制代码
int main()
{
    int        i = 6;  // 普通整型变量
	int *const p = &i; // 常指针

	int j = 8;

    // ×: p是常指针,无法修改其指向
    p = &j;

	// ×: const_cast 不能去除常指针的 const 属性
	const_cast<int *>(p) = &j;
}

上述代码以 const 属性为例,讨论变量的 volatile 属性时是完全一样的。

3.2 新式转换 static_cast

static 意味着静态转换,静态的含义是操作的过程只发生在编译阶段,而不是运行阶段,静态转换不涉及类型推理。

增加可读性

c++ 复制代码
int main()
{
	float f = 3.14;

	// 旧式类型转换
	int i = (int)f;
	int i = int(f);
	
	// 新式静态转换,等价于旧式转换:
	// 但是,新式静态强转更具可读性,更容易被查找
	int i = static_cast<int>(f); 
}

提高安全性

对于旧式类型转换,奉行了C语言的一贯作风:基本不进行任何逻辑判定,将灵活性和责任都丢给开发者。这样做的后果是可能会在某些比较难以察觉的地方埋下隐患,使用 static_cast 可以避免某些隐患。

c++ 复制代码
int main()
{
    int i = 6; // 普通整型数据
	float *pf; // 普通浮点指针

	// 旧式转换不进行任何合理性检查
	// 下面的代码,可以将类型问题瞒天过海
	// 编译器让其畅行无阻,开发者肉眼也难以察觉
	pf = (float *)&i; // float * 与 int * 不兼容,照样通过编译


	// 使用 static_cast 遇到非兼容性类型转换,会提出警告甚至错误
	pf = static_cast<float *>(&i); // float * 与 int * 不兼容
}

注意,虽然 static_cast 可以将不兼容的普通数据类型转换明确指出来,但对于代际类类型的上下层转换无能为力,对于类类型的代际上行转换或下行转换,需要借助 dynamic_cast 去保证运行的安全性,这个知识点要等到学完类之后再展开。

4. 关键字auto

在C语言中,auto 用来声明一个存储在 的变量,因此它只能用来修饰临时变量,不能用来修饰全局变量、静态变量,与此同时临时变量本身默认就是存储在栈中,因此在C语言中,auto 基本上是作废的。

在C++中,auto 代表自动获得数据的类型,比如:

c++ 复制代码
auto a = 100; // 等价于: int a = 100;

当然,上述代码仅是语法示例,无法体现 auto 的价值,在C++的函数模板、类模板中,利用 auto 自动获得数据类型,往往有奇效,例如:

c++ 复制代码
// 以下函数是一个模板,接收一个类型为 T 的容器
// 注意:类型 T 是动态的,可变的,不定的。
template <typename T>
void show(T &container)
{
    // 利用 auto 动态获取未知类型容器的相关数据
    auto it = container.begin();
    ...
    ...
}
相关推荐
虾球xz3 分钟前
CppCon 2015 学习:3D Face Tracking and Reconstruction using Modern C++
开发语言·c++·学习·3d
林鸿群6 分钟前
C#子线程更新主线程UI及委托回调使用示例
开发语言·c#
small_wh1te_coder1 小时前
c语言超详细知识点总结 1500行手写源码 持续更新中ing 从25年5月到6月5日
c++·c
SteveDraw3 小时前
C++动态链接库封装,供C#/C++ 等编程语言使用——C++动态链接库概述(总)
开发语言·c++·c#·封装·动态链接库
十五年专注C++开发3 小时前
设计模式之单例模式(二): 心得体会
开发语言·c++·单例模式·设计模式
?!7143 小时前
算法打卡第18天
c++·算法
flyair_China3 小时前
【云架构】
开发语言·php
Chef_Chen3 小时前
从0开始学习R语言--Day20-ARIMA与格兰杰因果检验
开发语言·学习·r语言
zh_xuan3 小时前
c++ std::pair
开发语言·c++