C++基础语法学习(二):复合类型

笔者需要参与一项slam项目的开发,经年不用C++知识已经统统上交给了国家,尤其是现在用python炼丹调参不亦乐乎,怕是一时都改不过来习惯。
故决定速刷C++primer(六)一书,把忘掉的东西捡起来,希望不要和python搞混。
(只是熟悉语法的话看菜鸟教程查表更快,但是为了摸鱼汇报进度还是过一下书吧)

复合类型

数组

先举个例子int array1[12] = {3,4,5},声明数组类型和容量,数据不足默认补0,索引即用array[x]

字符串

字符串必定以“\0”结尾,为了避免初始化的麻烦,通常通过char array2[] = "I love python"直接写入字符串,系统会自动补\0

  • 这也导致c++里字符串常量和字符常量是一对容易混的概念。
    "S"'S'是两个不同的概念,"S"是字符串常量,实际上是S\0的数组,而'S'则是字符常量,在ASCII标准里存在内存中的就是83。
  • sizeof和strlen:sizeof()函数统计数组长度,而strlen统计字符串(不计空字符)长度,也可以调用方法,字符串.size()返回大小值。
  • strcpy(目标,源)复制函数,strcat(目标,源)拼接函数。strcmp(比较1,比较2)比较字符串是否相同,接收字符串地址。
  • 字符串输入:cin.getline(数组名称,数组长度),不保留换行符。
  • 字符串输入:cin.get(数组名称,数组长度),保留换行符,所以连续输入几行会出现问题,下一次调用get会把enter当作输入,所以需要cin.get(xx,xxx).get()来把enter跳过。但这是一个很好的检查验证的方式,比getline严谨。(未来会再探讨相关问题)
  • 当混合输入数字和字符串时就会遇到这种问题,输入数字后换行符还留在输入队列里,接下来调用cin.getline()就会读取换行符并识别为空。所以我们最好是把前面的输入都放在get方法里,如(cin >> 某变量).get()将换行符跳过读取新行。

String类

一个示例代码可以说明大多特性

#include <iostream>
#include <string>               // make string class available
int main()
{
    using namespace std;
    string s1 = "penguin";
    string s2, s3;

    cout << "You can assign one string object to another: s2 = s1\n";
    s2 = s1;
    cout << "s1: " << s1 << ", s2: " << s2 << endl;
    cout << "You can assign a C-style string to a string object.\n";
    cout << "s2 = \"buzzard\"\n";
    s2 = "buzzard";
    cout << "s2: " << s2 << endl;
    cout << "You can concatenate strings: s3 = s1 + s2\n";
    s3 = s1 + s2;
    cout << "s3: " << s3 << endl;
    cout << "You can append strings.\n";
    s1 += s2;
    cout <<"s1 += s2 yields s1 = " << s1 << endl;
    s2 += " for a day";
    cout <<"s2 += \" for a day\" yields s2 = " << s2 << endl;
    return 0; 
}
  • 输入:getline(cin,字符串);,这与读入数组的方法有所差异。
  • 为了在字符串里可以输入很多需要转义的字符,可以使用R"( 字符串 )",如果还想在字符串里显示)"等元素,可以自定义标识头R"自定义字符( )自定义字符"

结构

struct stru1
{
    string Company;
    float diameter;
    double Kcal;
};
stru1 name1 {"skdms s.ltd",24.5,886.9};
stru1 *pointer1 = new stru1;
stru1 *pointer2 = new stru1[5];
cin>> pointer1->diameter;
delete ...

这就是典型的结构声明与实例化。每一个结构体都有自己的结构名和内部定义的几个成员(属性),实例化结构为变量,可以初始化结构的成员值。也可以不实例化变量名,用指针初始化未命名的结构实例,以及结构数组。

指针

指针即地址,任何一个数据对象都有自己的数据类型和地址,因此也可以用地址(指针)来指代寻找对应的数据。
先给出两个关键符号,*作为解除指针的标识符,&作为数据的寻址符。
举个例子。
这里num1是变量,string是指针(地址):

int num1 = 12;
int* string;
string = &num1;
num1 string 用&num1获得地址 用*string获得地址对应的变量 num1 string
  • 指针需要声明指向值的类型,如int* AA,double* BB等,且每个指针都需要声明*
  • 指针初始化可以一步到胃。此时初始化的是指针而不是*指针
int num1 = 12;
int* string = &num1;
  • 指针必须初始化再去指代数据对象,否则数据可能无法寻址导致出错。

指针的真正用武之地在于,在运行阶段分配未命名的内存来存储值

new&delete

举个例子:int* pointer = new int;delete pointer,这样就分配了一个int需要的内存空间,内存地址即pointer,之后可以根据需要给*pointer赋值,当不再需要时可以通过delete释放内存,但是不会删除指针。

  • 通常变量会在栈中开辟内存空间,而new则是在heap里开辟空间。
  • delete需要与new成对使用,new占用内存,delete释放内存,但是指针不会被删除。
  • delete不能对同一内存块释放两次,但可以针对空指针。
  • 创建动态数组时指针指向第一个元素,删除时应带[]
  • 索引动态数组元素可以直接把指针当作数组名进行索引:
int* ptr2 = new int[8];
ptr2[0] = 0.1;ptr[1] = 0.2;ptr[2] = 0.3;
ptr2 +=1;//将内存地址移到下一元素
cout<<ptr[0];//此时指向了原来的ptr[1]
delete [] pointer;

我们可以用这一组合创建动态数组、动态结构、结构数组等

struct stru1{int a;char b;float c;};
char *pointer1 = new char[8];//创建动态数组
stru1 *pointer2 = new stru1;//创建动态结构
stru1 *pointer3 = new stru1[5];//创建结构数组
cout<< pointer->a << stru1[2].b;//动态结构调用需要->符号
delete...

类型混合

#include <iostream>
using namespace std;
struct antarctica_years_end{int year;};

int main()
{
    antarctica_years_end s01, s02, s03; 
    s01.year = 1998;
    antarctica_years_end * pa = &s02;
    pa->year = 1999;
    antarctica_years_end trio[3]; // array of 3 structures
    trio[0].year = 2003;
    std::cout << trio->year << std::endl;
    const antarctica_years_end * arp[3] = {&s01, &s02, &s03};
    cout << arp[1]->year << std::endl;
    const antarctica_years_end ** ppa = arp; 
    auto ppb = arp; // C++0x automatic type deduction
// or else use const antarctica_years_end ** ppb = arp; 
    cout << (*ppa)->year << std::endl;
    cout << (*(ppb+1))->year << std::endl;
    return 0;
}

数组(vector和array)

vector是动态数组,内置new和delete。效率低下;array是静态数组,更安全。使用前需要引用头文件。

double array1[4] = {2,1,4,6};
vector<double> array2(4);//容量可以不初始化指定,动态的优势
array<double,4> array3 = {12,23,34,45};

都是基础啦。


相关练习均已上传github

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值