IE盒子

搜索
查看: 98|回复: 0

【C 转 C++】001 复合变量 容器 迭代器

[复制链接]

4

主题

6

帖子

14

积分

新手上路

Rank: 1

积分
14
发表于 2022-12-21 19:23:23 | 显示全部楼层 |阅读模式
0. Cpp引言

C++ 是 C语言的高级扩充,能够全面兼容C语言又会发展出各种高阶性能。
由于C语言太过于原生,很多工具需要自己造轮子,没有类似C++的STL库之类的高阶库,在使用的时候会倾向于从源头开始做,所以略显繁琐。因此立本帖,记录C转C++过程当中遇到的困惑。
本帖主要侧重于C++于C的不同之处,从一个C程序员的视角重新审视C++
参考书籍:C++ Primer 5th 中文版
1. 输入输出

与C不同的是,基本的输入输出,需要调用std库,使用cout输出cin输入表达式,代替printf()与scanf():
using namespace std;
cout << x <<endl;
cin >> x;
甚至可以使用类进行封装,对类直接进行运算。
// 封装好的Sales_item 类
Sales_item item1, item2;
cin >> item1 >> item2; // 读取一对打印记录
cout << item1 + item2 << endl;
return 0;
输入输出:
input:
0-201-708345-x 3 20.00
0-201-708345-x 2 25.00

output:
0-201-708345-x 5 110 222. 变量

声明和定义

声明(declaration)和定义(definition)严格区分开,由于C++中的分离式编译(seperate compilation)机制,使得程序可以独立编译。
定义:用于为变量分配存储空间,还可为变量指定初始值。
声明:用于向程序表明变量的类型和名字
通常声明规定变量的类型和名称,定义对其进行了初始化。
变量可被定义一次,但是可以被多次声明。
C/C++/Java 是静态语言 + 强类型,JavaScript/PHP 是动态语言 + 弱类型,Python 是动态语言 + 强类型。
C++ 是一种静态类型(statically typed)语言,即在编译阶段检查类型。
C++ 使用作用域(Scope)的概念,分全局(global)作用域和块(block)作用域。
3. 复合类型

引用

引用是一种C++独有的类型。
左值引用(lvalue reference),实质上是给对象起了一个另外的名字,初始化完成,引用与初始值绑定一起。
int value = 1024;
int &refVal = value;    // refVal 是 value 的另一个名字
int &refVal_2;          // 错误: 引用必须被初始化
空指针

空指针可以通过nullptr直接赋值,来初始化指针。C中,NULL是在cstdlib 库内定义的宏。
void指针

void *指针是一种特殊类型指针,可以存放任意对象的地址。
这一点在C语言也有,一般形参会使用void类型指针,然后入参后进行强制类型转换。
指向指针的引用

int i = 42;
int *p;         //
int *&r = p;    // r是一个对p指针的引用(int类型指针)
如何知道r的类型到底是什么,需要从右阅读r的定义,离变量最近的符号(&)对其类型最直接影响,因此本例中r是引用。
const 限定符

对于单纯常量,最好以 const 对象或 enum 替换 #define;
对于函数形式的宏,最好改用 inline 函数替换 #define。
出自《Effective C++》
对const应用时,必须使用const限定词,保证类型统一:
const int ci = 1024;
const int &r1 = ci; // 正确
int &r2 = ci; // 错误
类型别名 typedef 与 using

using是新方法:别名声明(alias declaration)
using SI = int; // SI 是int的同义词
auto 说明符

auto 可以 自动分析 数据类型
struct类定义

C++中的struct被赋予类的定义,内部的数据成员变量可以拥有类内初始值(in-class initializer) 在使用struct定义对象时,会默认对象的成员变量值为初始化值。
4. 命名空间using使用

在函数外使用using namespace :: name声明,可以不用在每次使用name时候加上namespace 在头文件时不应该包含using声明
5. string库类型

string 和 vector 是两种最重要的标准库类型,前者可以支持可变长字符串,后者可以支持可变长的集合。
与c中使用字符型数组表示字符串不同,C++使用string类型表示字符串,并且是变长的。
string初始化

/* 初始化字符串 */
string s4(n,'c');           // s4 是"cc...c"(n个)
string s1;                  // 空字符串
string s2 = s1;             // s2是s1 副本
string s3(s1);              // 等价于上
string s3("Lambertt");      // 等价于上
string对象的操作

cin >> string s的话会忽略空格,遇到空格即停止,类似scanf()函数 getline(cin,line)将输入读取并存储给string line,读取过程中保留空白字符直至遇到换行符(换行符也被读入),类似get()函数 使用s1+s2直接可以对字符串进行拼接,不需要使用strcpy()函数
字面量的字符串不能直接相加,必须至少有一个string变量。
6. 新的for循环表示

C++使用一种新的for循环方式
for(declaration : expression){
    statement;
}
// 每次迭代都会被初始化成为expression的下一个元素值
例如:
string str("something");
for (auto c: str){
    cout << c << endl;
}
输出:
s
o
m
e
t
h
i
n
g
P
在for循环中使用引用
string str("something");
for (auto &c: str){
    c= toupper(c);
}
cout << str << endl;
输出:
SOMETHING7. vector容器

vector是一种类模板,使用一对尖括号,在括号里放置信息表示进行实例化。
vector<int> nums;
//nums 保存了int 类型的对象
vector初始化

vector<T> v1;           // 默认空
vector<T> v1(v2);
vector<T> v1 = v2;      // 同上
vector<T> v1(n, val);   // 多个重复元素
vector<T> v1{1, 2, 3};  // 每个元素被赋予相应初始值
vector<T> v1 = {1, 2, 3};// 同上
注意,使用{}和()含义明显不同: - () 构造(construct)vector对象; - {} 初始化(initialize)vector对象;
vector添加元素,v.push_back向尾部添加元素
8. 迭代器

迭代器类似指针,可以通过解引用返回所指元素,但是存在差别。
// 把字符串首字符改为大写
string s("some string");
if (s.begin() != s.end());
{
    auto it = s.begin();
    *it = toupper(*it);
}
迭代器可以不用担心指针越界行为。
// 把字符串全部改成大写
string s("sometimes");
for(auto it = s.begin(); it != s.end()&& !isspace(*it);++it){
    *it = toupper(*it);
}
C++中经常使用 == 和!=在循环语句中,较少使用<。
9. 数组

与C中的数组类似,C++中数组有标准库函数beigin和end;
int a[] = {0,1,2,3,4,5,6,7,8,9};
int *beg   = begin(a);      // 指向ia首元素指针。
int *last  = end(a);        // 指向数组a尾元素的下一个指针
指针相减可以使用ptrdiff_t标准库类型,是一种带符号的类型。
ptrdiff_t diff = last - beg;
    cout << "diff between begin and end is " << diff << endl;
输出:
10
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表