C++ Notes (5)

@The Cherno C++ Series ( p31 - p35 )

Array

  1. 栈上创建数组
int example[5];
int* ptr = example;

//赋值的不同表达方式
example[2] = 6;
*(ptr + 2) = 6;
*((int*)(char*)ptr + 8) = 6;
//偏移多少取决于指针类型
  1. 堆上创建数组
int* another = new int[5];
another[2] = 6;
delete[] another;

这种方式存在内存间接寻址,如果要访问数组成员,就会在内存中跳跃,可能会影响性能。应该选择栈上创建数组来避免。

  1. C++11中有std :: array 有很多优点,边界检查、获取数组大小等;
    在堆上创建数组没有办法知道数组大小,也有但不可靠;
    在栈上创建可以通过知道数组大小。
//std
std::array<int,5> another;
another.size();
//栈上创建数组
//方法1
int a[5];
int count = sizeof(a) / sizeof(int);
//方法2
//example_size 必须固定不变
static const int example_size = 5;
int example[example_size];

String

std::string 构造函数接受 参数const char或 char

#include <iostream>
#include <string>

//方法1
std::string name = "cherno";
name += "hello";

//方法2
std::string name = std::string("cherno") + "hello";

bool contains = name.find("no") != std::string::npos;
std::cout << name << std::endl;

//在函数中传递string, 这里相当于copy string,在heap上动态分配一个新的字符数组; string copy 其实很慢,so可以用引用
//这里有一点点疑问?不应该是在栈上吗?
//string类 有一个私有成员char* 在栈上,记录堆上分配内存的地址,实际数据是储存在堆上的。
void printString(std::string string)
{
    string += 'h';
    std::cout << string <<std::endl;
}

//引用 + const 承诺不修改
void printString(const std::string& string)
{
    std::cout << string <<std::endl;
}

string literals

  1. 字符串的结束 ‘\0’
  2. 一些使用
char *name = "cherno";
name[2] = 'a'; // error

char name[] = "cherno";
name[2] = 'a'; // right

//C++11中 clang编译器只会让你编译 const char*
char *name = (char*)"charno";

//宽字符
const wchar_t *name2 = L"Cherno"; 
//具体占几个字节是由编译器决定的 windows 2字节 linux 4字节 mac 4字节,所以是一个变动的值,如果确定要2字节,可以定义char16_t

//不同类型的字符
const char16_t *name3 = u"Cherno";
const char16_t *name4 = U"Cherno";

const char* name = u8"Cherno";

//C++14中 提供了一些方法append
using namespace std::string_literals;
//方法1
std::string name0 = "cherno"s + "hello";

//方法2
//R忽略转义字符
const char* example = R"(line1
line2
line3
line4)";

//方法3
const char* ex = "line1"
"line2"
"line3";

//类型
std::wstring name1 = L"Charno"s + L"hello";
//u32string
  1. 内存:string literals 永远只在只读区域。

Const

  1. 包含常量和只读两层含义
  2. const int* a :不能修改a指针指向的内容,可以指向别的东西,等同于int const* a。
  3. int* const a:与上面的相反,可以改变指针指向的内容,但是不能指向别的东西。
  4. const int* const a:都不能改变。
  5. const在类中的使用
class Entity
{
private:
    int m_X, m_Y;
    
public:
    //这个方法不会修改类成员变量,只能读
    int GetX() const
    {
       return m_X;
    }
    int GetX() 
    {
       return m_X;
    }
    void SetX(int x)
    {
       m_X = x;
    }
    
};

void PrintEntity(const Entity& e)
{
   //这里是调用const方法
   std::cout << e.GetX() << std::endl;
}



class Entity
{
private:
    int* m_X, m_Y; //这里注意 m_X是指针 m_Y是int
    //int*  m_X, *m_Y; //两个都是指针
public:
    //这个方法不能改变实际的Entity类
    //包括指针本身以及指针所指的内容
    const int* const GetX() const
    {
       retun m_X;
    }
}

mutable

  1. 如果const方法要修改成员变量,那就标记为mutable (90%使用场景)
class Entity
{
private:
    int m_X, m_Y;
    mutable int z;
public:
    //这个方法不会修改类成员变量,只能读
    int GetX() const
    {
       z = 2;
       return m_X;
    }
    int GetX() 
    {
       return m_X;
    }
 };
  1. 运用在lambda表达式中(很少用,几乎无)
int main()
{
    
    int x = 8;
    //lambda一次性小函数
    //auto f = [=]() //只是传值
    //auto f = [&]()
    //auto f = [&x]()
    //auto f = [x]()
    auto f = [=]()
    {
        int y = x;
        y++;
        std::cout << y << std::endl;
        std::cout << "hello" << std::endl;
    };
    等同于>>>>>>>
    auto f = [=]() mutable
    {
        x++;
        std::cout << x << std::endl;
        std::cout << "hello" << std::endl;
    };
    f();
    std::cout << x << std::endl;
    //这里控制台的显示是分别是 9 hello 8
    //说明mutable在lambda中只是复制的8
 }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值