2020-12-25

C++17入門經(jīng)典上

Chapter 1 基本概念

  1. 頭文件包含許多內(nèi)容呼巴,其中包括.cpp文件中的可執(zhí)行代碼使用的函數(shù)原型,以及使用的類和模板的定義
  2. 預(yù)處理指令會(huì)以某種方式修改源代碼盈滴,之后會(huì)把他們編譯為可執(zhí)行的形式
  3. 頭文件的內(nèi)容會(huì)添加到源文件中
  4. 頭文件的內(nèi)容被插入到#include指令的位置
  5. 流是數(shù)據(jù)源或數(shù)據(jù)接收器的一種抽象表示账劲,每個(gè)流都關(guān)聯(lián)著某臺(tái)設(shè)備奕短,關(guān)聯(lián)著數(shù)據(jù)源的流就是輸入流婉刀,關(guān)聯(lián)著目的地的流就是輸出流
  6. 名稱空間類似于姓氏
  7. 兩個(gè)冒號(hào)::有一個(gè)非常奇特的名稱帜平,作用域解析運(yùn)算符
  8. main函數(shù)不能定義在名稱空間中幽告,未在名稱空間中定義的內(nèi)容都存在于全局名稱空間中,全局名稱空間沒有名稱
  9. 不要使用以下劃線開頭的名稱
  10. 有時(shí)候程序需要幾個(gè)類似的類或函數(shù)裆甩,其代碼中只有所處理的數(shù)據(jù)類型有區(qū)別冗锁,編譯器使用模板給特定的自定義類型自動(dòng)生成類或函數(shù)代碼

Chapter 2 基本數(shù)據(jù)類型

  1. 花括號(hào)稱為初始化列表,初始化列表可以包含幾個(gè)值嗤栓;優(yōu)勢(shì):允許以相同的方式初始化所有變量冻河,被稱為統(tǒng)一初始化
    1. 可以在花括號(hào)中使用單個(gè)值來初始化任何變量 c++17
int apple_count{12};    
int counter{};//零初始化 {}相當(dāng)于0
const unsigned toe_count{10};//常量
  1. const 可以固定任何類型的變量值箍邮,不可被修改
  2. unsigned 是無符號(hào)數(shù),永遠(yuǎn)不會(huì)是負(fù)值
  3. 整數(shù)除法返回的是分母除以分子得到的倍數(shù)叨叙,任何余數(shù)都會(huì)被舍棄
  4. 浮點(diǎn)類型數(shù)據(jù)不能使用unsigned或signed修飾符锭弊,浮點(diǎn)類型總是帶符號(hào)的
  5. cmath頭文件中的所有函數(shù)可接受任意浮點(diǎn)類型或整型參數(shù)
    1. abs(arg)
    2. ceil(arg)
    3. floor(arg)
    4. exp(arg)
    5. sqrt(arg)
    6. round(arg)
    7. pow(arg1,arg2)
    8. tan(angle)
  6. iomanip頭文件,控制數(shù)據(jù)格式
    1. fixed 用小數(shù)點(diǎn)固定格式
    2. dec 十進(jìn)制格式
    3. left 左對(duì)齊格式
    4. setprecision(n) 一共n位輸出擂错,if有fixed味滞,則表示小數(shù)點(diǎn)后n位數(shù)字
    5. setw(n) 輸出序列寬度
    6. setfill(ch) ch填充多余,默認(rèn)是空格
  7. static_cast<要轉(zhuǎn)的新類型>(數(shù)據(jù)) 強(qiáng)制類型轉(zhuǎn)換
  8. auto 關(guān)鍵字可以告訴編譯器應(yīng)推斷數(shù)據(jù)類型
auto num{10};   

Chapter 3 處理基本數(shù)據(jù)類型

  1. 枚舉 定義:
enum class 類名:指定成員的類型{枚舉成員1,...,枚舉成員n};//默認(rèn)枚舉成員1 = 0钮呀,后一個(gè)比前一個(gè)大1
//           成員類型可以省略不寫

可以當(dāng)成類來看待剑鞍,就是一個(gè)類名數(shù)據(jù)類型,引用枚舉時(shí)行楞,必須使用類型名(類名)來限定他

枚舉成員的值必須是編譯器可以計(jì)算出來的常量表達(dá)式攒暇,這種表達(dá)式包括字面量,以前定義的枚舉成員子房,聲明為const的變量形用,不能使用非const變量(即使使用字面量初始化也不行)

enum class Punctuation : char{Comma=',',Exclamation='!',Question='?'};
  1. using關(guān)鍵字允許把自己的數(shù)據(jù)類型名稱指定為另一個(gè)類型的替代名稱
using BigOnes = unsigned long long;
  1. 全局變量的初始化在main()開始之前進(jìn)行,默認(rèn)情況下被初始化為0.局部變量將全局變量隱藏時(shí)证杭,使用作用域解析運(yùn)算符(::)來限定它

Chapter 4 決策

  1. cctype頭文件

    1. isupper(c) c是否是大寫字母
    2. isalpha(c) c是否是字母
    3. isdigit(c) c是否是數(shù)字
    4. isspace(c) c是否是空白田度,\n \t \r \f ' '
    5. isblank(c) c是否是空格 ‘ ’ \t‘
    6. tolower(c) 返回c的小寫
    7. isalnum(c) if c 包含字母或數(shù)字,就返回一個(gè)正整數(shù)(true)else 0(false)
  2. if(變量){} == if(變量!=0) == if(變量!=false) //內(nèi)解愤! 外==

  3. if(!變量){} == if(變量==0) == if(變量==false)

Chapter 5 數(shù)組和循環(huán)

數(shù)組

  1. 數(shù)組的大小必須用常量表達(dá)式來指定
  2. 數(shù)組沒有初始化镇饺,所以包含的都是垃圾值
double temp[100];
temp[3] = 99.0;
unsigned int height[6];
unsigned int height1[6]{1,2,3,4,5,6};
int height3[6] {};// all 0
const int height4[6]{1,2,3,4,5,6};
  1. size_t 是某個(gè)不帶符號(hào)的整數(shù)類型的別名,足夠大送讲,能夠容納編譯器支持的任何類型(包括數(shù)組)
  2. 幻數(shù):產(chǎn)量值的多次使用直接定義為const
  3. 數(shù)組大小一般設(shè)置為unsigned奸笤,一般不會(huì)為負(fù)值
  4. std::size(array); 獲取數(shù)組的大小,c++17
  5. c++可以使用浮點(diǎn)數(shù)來控制for循環(huán)
//無限循環(huán)中哼鬓,輸入指定個(gè)數(shù)元素
x[count] = input;
if(++count == size){
    cout<<"無法容納"<<size<<"個(gè)元素"<<endl;
    break;
}
  1. 無符號(hào)數(shù)減去值時(shí)候應(yīng)該小心监右,0-1=numice_limits<size>::max()
  2. 字符數(shù)組初始化字符串字面量,默認(rèn)會(huì)加上 ’\0‘
char name{"aeiou"};
//6 elements
//因?yàn)樽址淖詈筇砑恿?\0'來標(biāo)記字符串結(jié)束异希,所以數(shù)組包含6個(gè)元素
  1. 使用數(shù)組名不能輸出數(shù)值類型的數(shù)組的內(nèi)容健盒,這種方法僅僅用于輸出char數(shù)組,即使是傳送給輸出流的char數(shù)組称簿,也必須用空字符結(jié)束扣癣,否則程序很可能崩潰
const int maxLength{100};
char text[maxLength]{}
for(int i{};text[i]!='\0';i++){//一個(gè)字符數(shù)組中的原因個(gè)數(shù)
    if(isalpha(text[i])){
        switch(tolower(text[i])){
            case 'a':case 'e':case 'i': case 'o' :case 'u':
            ++vowels;
            break;
            default:
                ++consonants;
        }
    }
}
  1. 不能使用cin>>直接讀取輸入內(nèi)容,因?yàn)?gt;>不能碰到空格
  2. cin.getline(text,maxlength);
  3. 多維數(shù)組和一維的類似憨降,空初始化列表是將其初始化為0
  4. 多維數(shù)組除了第一個(gè)緯度之外父虑,必須指定大小,編譯器只能推斷第一個(gè)緯度的大小
  5. 在運(yùn)行期間給數(shù)組分配內(nèi)存空間
cin>>count;
unsigned int height[count];
//此時(shí)數(shù)組無法初始化授药,因?yàn)椴恢烙卸嗌僭亍?//因此這種帶有變量個(gè)數(shù)的數(shù)組频轿,只能先聲明,后賦值,不可直接初始化

數(shù)組的替代品(優(yōu)于數(shù)組)

std::array

array<T,N>

include<array>

  1. if 創(chuàng)建array<>容器但不指定初始值赚窃,則數(shù)組也包含垃圾值
  2. fill()函數(shù)把所有元素設(shè)置為某個(gè)給定的值
array<double,100> values{};
values.fill(3.1415);// all elements to pi
  1. array.size(); 返回?cái)?shù)組的元素個(gè)數(shù)size_t類型键痛,array對(duì)象總是可以通過size()函數(shù)確定自己的大小
  2. array.at(i); 返回i出的值昨忆,i是一個(gè)索引
  3. array.front();返回?cái)?shù)組第一個(gè)值
  4. array.back();返回?cái)?shù)組最后一個(gè)值
  5. 兩個(gè)array只要容器大小相同拢驾,存儲(chǔ)類型相同嵌洼,可以使用== != > < 對(duì)兩個(gè)array中的元素進(jìn)行逐個(gè)比對(duì)鳖昌,也可相互賦值

std::vector<T>

  1. 大小可自動(dòng)增加糕档,可容納任意數(shù)量元素
  2. push_back(X);向vector中添加元素
vector<long> numbers(20,99L);//理解為構(gòu)造器()捶惜,20個(gè) 99
vector<int> number(20);//有20個(gè)0
vector<long> number{20};//只有一個(gè)20
vector<unsigned int> primes{1,2,3,4,4,4};//初始化{}列表
  1. 與array類似陪捷,兩個(gè)vector也可以比較苍碟,但是vector可以元素?cái)?shù)量不同的比蜓肆,字典序比較
  2. 一個(gè)vector給另外一個(gè)vector賦值時(shí),被賦值的會(huì)被覆蓋已經(jīng)存在的值
  3. vector可以存儲(chǔ)在其他容器中
  4. vector沒有fill()成員,但是提供了assign函數(shù)黎烈,可用于重新初始化vector<>內(nèi)容
vector<long> numbers(20,99L);//20個(gè)99
numbers.assign(99,20L);//99個(gè)20
numbers.assign({99L,20L});//99 和 20
numbers.clear();//清空numbers
numbers.empty()//vector中是空趴捅,沒有數(shù)據(jù)嗎?返回true orfalse
numbers.pop_back();//刪除vector最后一個(gè)元素

如果編譯時(shí)知道元素的準(zhǔn)確數(shù)量霹疫,就是用array<>,如果不知道就是用vector<>

Chapter 6 指針和引用

指針

  1. 指針是可存儲(chǔ)地址的變量拱绑。他指向內(nèi)存中存儲(chǔ)了其他值的位置
  2. 初始化列表為空,所以這個(gè)語句把pnumber初始化為等價(jià)于0的指針丽蝎,即不指向任何內(nèi)容的地址猎拨,等價(jià)于0的指針寫為nullptr
long* pnumber{nullptr};
long *pnumber{nullptr};
  1. 定義指針時(shí),總是要初始化他屠阻,如果還不能為指針提供期望的值红省,就將其初始化為nullptr
  2. 最好在單獨(dú)的代碼行上聲明指針和普通變量,以避免出現(xiàn)這種混淆国觉。
  3. 不管指針指向什么類型或大小的數(shù)據(jù)吧恃,指針變量本身的大小始終是相同的,如今的平臺(tái)上指針變量大小一般是4或8字節(jié)

地址運(yùn)算符&

  1. &是一個(gè)一元運(yùn)算符麻诀,他可以獲取變量的地址痕寓。
  2. &運(yùn)算符可以應(yīng)用于任何類型的變量,但必須在對(duì)應(yīng)類型的指針中存儲(chǔ)地址
  3. 使用編譯器推斷指針類型蝇闭,但是盡量還是使用auto*
auto* number{&height};
  1. 使用auto*聲明的變量只能用指針值初始化呻率,使用其他類型的值初始化,會(huì)導(dǎo)致編譯錯(cuò)誤丁眼。

間接運(yùn)算符

  1. 將間接運(yùn)算符*應(yīng)用于指針筷凤,可以訪問指針?biāo)赶虻膬?nèi)存位置的數(shù)據(jù)昭殉,也成為為解引用運(yùn)算符
int count{};
int* pount{&count};
  1. *是乘法運(yùn)算符苞七,間接運(yùn)算符藐守,還可以應(yīng)用于聲明指針,一般編譯器根據(jù)上下文分析
  2. 使用指針的用處
    1. 動(dòng)態(tài)的為新變量分配內(nèi)存空間蹂风,即可以在程序執(zhí)行過程中分配
    2. 使用指針表示法操作存儲(chǔ)在數(shù)組中的數(shù)據(jù)卢厂,與普通數(shù)組表示法完全等效
    3. 指針可以在函數(shù)中訪問函數(shù)外部定義的大塊數(shù)據(jù)
    4. 指針是支持多態(tài)性起作用的基礎(chǔ)

char類型的指針

  1. 指向char類型的變量,可以用字符串字面量(實(shí)際上是const char類型的數(shù)組)初始化
  2. 給未解除引用的char類型指針應(yīng)用<<插入運(yùn)算符-----假定這種指針包含以空字符結(jié)尾的字符串的地址
  3. 如果給解除引用的char類型指針應(yīng)用<<插入運(yùn)算符---將地址中的單個(gè)字符寫入cout
const char* pproverb{"A miss is as good as a mail"};
void proj1() 
{
    const char* pstr1{ "fatty arb" };
    const char* pstr2{ "clara bow" };
    const char* pstr3{ "lassie" };
    const char* pstr{ "your lucky star is " };
    cout << "pick a lucky star! enter a number between 1 and 3:" << endl;
    size_t choice{};
    cin >> choice;
    switch (choice)
    {
        case 1:cout << pstr << pstr1 << endl; break;//your lucky star is fatty arb
        case 2:cout << pstr << pstr2 << endl; break;//字符串名字直接輸出字符串
        case 3:cout << pstr << pstr3 << endl; break;//未解除引用
        default:cout << "sorry you haven't got a lucky star." << endl;
    }
    cout << *pstr1 << endl;//輸出首字符(首地址)   解除引用
}
  1. 指針數(shù)組

每個(gè)因子都是一個(gè)const char* 惠啄,一個(gè)const char* 指向一個(gè)字符串字面量

其中的*pstr[i] 無法進(jìn)行再賦值慎恒,因?yàn)槠錇槌A縞onst,無法進(jìn)行修改

void proj2()
{
    const char* pstars[] = {//默認(rèn)都會(huì)加上\0
        "fatty","clara","lassie","slim","boris","mae","oliver","greta"
    };
    //pstars[]數(shù)組中的每個(gè)元素 會(huì)指向一個(gè)const char類型的變量(串/字符數(shù)組)
    cout << "pick a lucky star! enter a number between 1 and " << size(pstars) << endl;
    int choice{};
    cin >> choice;
    if (choice>0 &&choice<size(pstars))
    {
        cout << "your lucky star is " << pstars[choice - 1] << endl;
    }
    else
    {
        cout << "sorry!" << endl;
    }
    pstars[0] = pstars[1];//數(shù)組內(nèi)部可以相互賦值撵渡,就很離譜H诩怼!
}//指針數(shù)組法

把一個(gè)聲明從右向左讀趋距。

char * const cp; ( * 讀成 pointer to指向 ) 
cp is a const pointer to char 

const char * p; 
p is a pointer to const char; 

    const char* my_favorite_star{ "Lassie" };
    my_favorite_star = "Mae";//my_favorite_star本身不是const變量粒氧,                               my_favorite_star = pstars[1];
  1. 指向常量的指針

指針指向的內(nèi)容不能修改,但可以把指針設(shè)置為指向其他內(nèi)容

const char* pstring{"some text that cannot be changed"};
const int value{20};
const int* pvalue{&value};
int a{ 1 };
pvalue = &a;

value是一個(gè)常量节腐,不能修改外盯,pvalue是一個(gè)指向常量的指針,可以用于存儲(chǔ)value的地址翼雀。不能在非const int指針中存儲(chǔ)value的地址饱苟。

但是可以把非const變量賦給pvalue、

  1. 常量指針

存儲(chǔ)在指針中的地址不能修改狼渊。

只能指向初始化時(shí)指定的地址箱熬。

但是地址的內(nèi)容不是常量,可以修改囤锉,

int data{ 20 }; 
int* const pdata{ &data }; 
*pdata = 25;//內(nèi)容可變
  1. 指向常量的常量指針

因?yàn)榇鎯?chǔ)在指針中的地址和指針指向的內(nèi)容都被聲明為常量坦弟,所以兩者都不能修改

const float value{3.14};
const float* const pvalue{&value};

指針和數(shù)組

  1. 數(shù)組名可以像指針那樣操作,輸出時(shí)官地,使用非char類型的數(shù)組名酿傍,就可以得到內(nèi)存中的地址。
int num[]{ 1,2,3 };
cout << num << endl;
  1. 指針可進(jìn)行的運(yùn)算:

    1. 加減:(在數(shù)組中表現(xiàn)為向后/前移動(dòng)一位驱入,就是一個(gè)類型的字節(jié)數(shù))

      • 指針+整數(shù)=指針

        int data[]{1,2,4};
        int* pdata{&data[1]};
        cout<<* (pdata+1)<<endl;//4
        
      • 指針-整數(shù)=指針

      • 指針+-指針=整數(shù)(類型相同赤炒,同一數(shù)組中)

      結(jié)果是兩個(gè)索引的差值

    2. 比較

動(dòng)態(tài)內(nèi)存分配

  1. 所有指針都應(yīng)該初始化,如果指針沒有包含合法的地址亏较,就應(yīng)該總讓他包含nullptr
double* pvalue{new double{}};//初始化為0.0
double* pnull{};//初始化為nullptr
delete pvalue;
pvalue = nullptr;
  1. delete 只是將自由存儲(chǔ)區(qū)的內(nèi)存釋放莺褒,變量還可以使用,但是最好先將其置為nullptr

  2. 與普通數(shù)組不同的是雪情,無法讓編譯器推斷出動(dòng)態(tài)分配數(shù)組的維數(shù)

double* data{new double[100]};//100個(gè)垃圾值
int* num{new int[100]{0}};//100個(gè)0
int* one{new int[]{1,2,3}};//報(bào)錯(cuò)遵岩,無法推斷
delete[] data;//釋放動(dòng)態(tài)數(shù)組的內(nèi)存
data=nullptr;
  1. 釋放動(dòng)態(tài)數(shù)組的內(nèi)存,使用delete[] 或者delete [] 方括號(hào)表示刪除的數(shù)組
  2. ->指針選擇成員
  3. 多維動(dòng)態(tài)數(shù)組?
void proj6()
{
    int rows{ 3 };
    int columns{ 3 };
    //動(dòng)態(tài)二維數(shù)組
    //carrots數(shù)組是double*指針的一個(gè)動(dòng)態(tài)數(shù)組尘执,每個(gè)double*指針包含一個(gè)double數(shù)組的地址
    double** carrots{ new double* [rows]{} };
    for (size_t i = 0; i < rows; i++)
    {
        carrots[i] = new double[columns] {};
    }

    for (size_t i = 0; i < rows; i++)
    {
        delete[] carrots[i];
    }
    delete[] carrots;
}
  1. 每個(gè)new必須對(duì)應(yīng)一個(gè)delete舍哄,每個(gè)new[] 必須對(duì)應(yīng)一個(gè)delete[]
  2. 在c++程序設(shè)計(jì)中,盡量不要使用new delete new[] delete[]誊锭,應(yīng)該使用vector<> 和智能指針來規(guī)避動(dòng)態(tài)內(nèi)存的一些風(fēng)險(xiǎn)表悬。盡量避免直接操作動(dòng)態(tài)內(nèi)存。

智能指針

  1. 不必使用delete delete[] 運(yùn)算符釋放內(nèi)存

  2. 智能指針不能進(jìn)行遞增或遞減丧靡,也不能進(jìn)行算術(shù)操作

  3. <memory>頭文件

  4. 三種智能指針

    1. unique_ptr<T>

      1. 這個(gè)對(duì)象類似于指向T類型的指針蟆沫,是惟一的。
      2. 從不會(huì)有兩個(gè)unique_ptr<>對(duì)象指向同一地址
      3. 指向的值被該對(duì)象獨(dú)占
      unique_ptr<double> pdata{ new double{999.0} };
      cout << pdata << endl;//地址
      cout << *pdata << endl;//數(shù)值
      cout << pdata.get() << endl;//get()函數(shù)返回地址
      unique_ptr<double> pdata1{ make_unique<double>(999.0) };
      auto pdata2{ make_unique<double>(1.9) };//
      //三個(gè)方法相同温治,推薦最后一種寫法饭庞,簡潔,且可以防止內(nèi)存泄漏
      
      1. reset() 將指針重置為nullptr熬荆,如果參數(shù)不設(shè)置值但绕,就是nullptr

      2. release() 將智能指針轉(zhuǎn)換為普通指針,注意惶看,將其轉(zhuǎn)化為原始指針之前一定要先保存原始指針再進(jìn)行釋放捏顺,否則將出現(xiàn)內(nèi)存泄漏的情況

        const size_t n{ 100 };
        unique_ptr<double[]> pvalues{ new double[n] };
        auto pvalues1{ new double[n] };
        auto pvalues2{ make_unique<double[]>(n) };//動(dòng)態(tài)創(chuàng)建n個(gè)元素的數(shù)組
        cout << pvalues1 << endl;//地址
        for (size_t i = 0; i < n; i++)
        {
           pvalues2[i] = i + 1;
        }
        /*for (size_t i = 0; i < n; i++)
        {
           cout << pvalues2[i] << endl;
        }*/
        pvalues.reset();//將指針重置為nullptr
        double* values = pvalues2.release();
        delete values;
        
  1. shared_ptr<T>

    1. 創(chuàng)建shared_ptr<T> 過程更復(fù)雜一些,主要是需要維護(hù)引用計(jì)數(shù)纬黎,

      void proj8()
      {
         shared_ptr<double> pdata{ new double{111.1} };
         shared_ptr<double> pdata2;//初始化為nullptr
         pdata2 = pdata;
         cout << *pdata2 << endl;
      }
      
      1. 復(fù)制pdata會(huì)增加引用次數(shù)幅骄,兩個(gè)指針必須重置或釋放,double變量占用的內(nèi)存才會(huì)釋放
      2. 實(shí)際使用共享指針的情況通常涉及對(duì)象
  2. weak_ptr<T>

理解引用

  1. 引用就是一個(gè)別名本今,可以用作某對(duì)象的別名拆座,不可以只聲明引用而不對(duì)其初始化
  2. 引用不能修改另一個(gè)另一個(gè)對(duì)象的別名
  3. 類型名后面&符號(hào)表示引用,如果取得引用的地址冠息,結(jié)果會(huì)是指向原始變量的一個(gè)指針

就當(dāng)做別名去理解挪凑,想不清楚就用原名

void proj9()
{
    double data{ 3.5 };
    double& rdata{ data };
    double* pdata1{ &rdata };
    double* pdata2{ &data };
    cout << (pdata1 == pdata2) << endl;//相等

    double* pdata{ &data };
    *pdata += 2.5;
    double other_data{ 5.0 };
    rdata = other_data;
    cout << rdata << endl;
}

Chapter 7 操作字符串

  1. c++的string頭文件定義了string類型,相比ctring頭文件中以‘\0’結(jié)尾的c字符串更可靠

  2. 定義string對(duì)象的六種方式

    1. empty
    2. 字面量
    3. 字面量切割
    4. 構(gòu)造器
    5. string對(duì)象
    6. string對(duì)象切割
string empty;//長度為0逛艰,不包含字符的字符串empty

string proverb{"many a mickle make a muckle."};//字面量

string part_literal{"least said soonest mended.",5};//least  字面量切割

string sleeping(6,'a');//6個(gè)a 構(gòu)造器

string sentence{proverb}; //string 對(duì)象

string sentence{proverb,0,13};//(begin,num) //string對(duì)象的切割

  1. c串與string串的轉(zhuǎn)化躏碳,(string 字符串的長度不會(huì)計(jì)算\0,但是有\(zhòng)0存在(不理它))

    1. string.c_str();
    2. string.data();
string proverb{"many a mickle make a muckle."};//字面量
const char* proverb_c_str = proverb.c_str();//const char* 類型字符串
//const char* 表示里面的字符是不能變化的散怖,但是proverb_c_str可以變菇绵,指別的地方
char* prover_data = proverb.data();//不是const
cout<<proverb.length();

  1. string對(duì)象的操作

    1. 賦值
      • 字面量賦值
      • 串變量賦值
    string adj{"hornwogging"};//字面量賦值
    string word{"ribbish"};
    word{adj};//串變量賦值
    adj = "twotiming";
    
    1. 連接
    • +連接:必須有一個(gè)string對(duì)象在+的一側(cè)
    • string.append(str,begin,end);連接
    • string.append(str,'字符');
    string word{"this is a string object"}
    string description{"whipppersnapper"+word};
    
    string compliment{"~~~what a beautiful name...~~~"};
    sentence.append(complient,3,22);//what a beautiful time 
    sentence.append(,'!');//!!!
    
    1. 數(shù)串連接:

    ? to_string(數(shù)字)+字符串

    double num{ 100.0 };
    string name{ "I'm Huang Hongwei.I am " };
    cout << name + to_string(num) + " years old" << endl;
    
  2. 讀入串getline(cin,text)

    string text{};
    getline(cin, text);
    cout << text << endl;
    
  3. 訪問子串

    • str.substr(be,num)

    • str.substr(be)

    • str.substr()//父子相同

    • out_of_range類型

      string phrase{ "The higher the fewer." };
      string word1{ phrase.substr(4,6) };
      cout << word1 << endl;
      
      string word2{ phrase.substr(4,100) };
      cout << word2 << endl;
      
      string word{ phrase.substr(4) };
      cout << word << endl;
      
      string str{ phrase.substr() };
      cout << str << endl;
      
  1. 比較字符串

    1. 字典序比較:

      • 前面的字符都相同镇眷,看長度咬最,越長越大
      • 長度相同,且對(duì)應(yīng)字符相同欠动,則相同
    2. string對(duì)象可以存儲(chǔ)到容器中永乌,普通的char數(shù)組不能存儲(chǔ)到容器中。std空間定義了一個(gè)非成員函數(shù)模板,實(shí)現(xiàn)效果與swap(a翅雏,b)相同

    3. compare()函數(shù)

      • obj. compare()函數(shù)可以比較該對(duì)象

        for(size_t i{1};i<names.size();++i)
        {
            if(names[i-1].compare(names[i]>0))
            {
                names[i].swap(names[i-1]);
                sorted = false;
            }
        }
        
    4. 使用substr()進(jìn)行比較

    string text{ "peter piper picked a peck of pickled pepper. " };
    string phrase{ "got to pick a pocket or two." };
    for (size_t i = 0; i < text.length()-3; i++)
    {
     if (text.substr(i,4)==phrase.substr(7,4))
     {
         cout << "text contains " << phrase.substr(7, 4) << " starting at index " << i << endl;
     }
    }
    

    ?

  2. 搜索字符串find()

string sentence{ "manners maketh man" };
string word{ "man" };
cout << sentence.find(word) << endl;
cout << sentence.find("ma")<< endl;
cout << sentence.find("k")<< endl;
cout << sentence.find("x")<< endl;//返回string:npos
  • find(串硝桩,對(duì)象的初始查找點(diǎn))
cout<< sentence.find("an",1);//從1開始查找,結(jié)果是1
cout<<sentence.finde("an",3);//從3開始查找枚荣,結(jié)果是16,第二次出現(xiàn)an的位置
  • 搜索任意字符集合find_first_of() find_last_of()

    ? 從頭開始 從結(jié)尾開始

    string text{"hjkld,ddddd ddddd ddd ddd \"};
    string operators{",.\""};
    cout<<text.find_first_of(operators)<<endl;//返回集合中(有一個(gè)匹配就返回)第一個(gè)出現(xiàn)的位置 5
    
  • find_first_not_of() find_last_not_off()

    搜索不在字符集合中的字符的位置

    cout<<text.find_first_not_of("aeiouAEIOU");//查找第一個(gè)不是元音的位置
    
  • 逆向搜索字符串str.rfind();

string sentence{"manners maketh man"};
string word{"an"};
cout<<sentence.rfind(word);//16  從后向前搜索啼肩,index=16是an第一次出現(xiàn)的地方
//從n開始搜索

  1. 修改字符串

    1. 插入 :索引位置前插入橄妆,充當(dāng)當(dāng)前索引insert()

      string phrase{ "we can insert a string." };
      string words{ "a string into " };
      //phrase.insert(14, words);//在14位置插入words
      cout << phrase << endl;
      
      phrase.insert(13, words, 8,5);  //words中從8開始的5個(gè)字符  插入到對(duì)象的13位置
      cout << phrase << endl;
      
  1. 替換

    string text{ "we can replace a string" };
    text.replace(1, 5, "123456");//在index=1的地方,的5 個(gè)字符夏志,替換為123456
    cout << text << endl;
    
  1. 刪除

    刪除[begin,]之后的len個(gè)字符

unsigned begin{ text.find('c') };
int len{ 3 };
cout << text.erase(begin,len) << endl;

將字符串轉(zhuǎn)化為整型

stoi(string)

string s{"12334"};
int i{stoi(s)};

Chapter 8 定義函數(shù)

返回類型 函數(shù)名 (參數(shù)列表)

{

}

  1. 函數(shù)調(diào)用中的實(shí)參順序必須對(duì)應(yīng)于函數(shù)列表里的參數(shù)順序研侣。函數(shù)名和參數(shù)列表的組合稱為函數(shù)的簽名俘闯。
  2. 函數(shù)體中可以有多個(gè)return語句,每個(gè)return語句可能返回不同的值慌随。
  3. 返回類型是void->return ;
  4. 函數(shù)原型=函數(shù)聲明:定義了函數(shù)名,函數(shù)的返回值躺同,參數(shù)列表阁猜;
  5. 聲明一定要放在調(diào)用之前。蹋艺。除非把實(shí)現(xiàn)寫在寫在引用之前剃袍。(同c語言)

給函數(shù)傳遞實(shí)參

如果指定的函數(shù)實(shí)參類型不對(duì)應(yīng)參數(shù)類型,編譯器就會(huì)把參數(shù)的類型隱式轉(zhuǎn)換為參數(shù)類型

按值傳送:

實(shí)參的變量值或常量值根本不會(huì)傳送給函數(shù)捎谨,而是創(chuàng)建實(shí)參的副本民效,把這些副本傳給函數(shù)。執(zhí)行完函數(shù)之后就廢棄副本(不會(huì)對(duì)原有的值進(jìn)行更改)

  1. 給函數(shù)傳遞指針:參數(shù)為指針類型時(shí)涛救,按值傳送機(jī)制就會(huì)像以前那樣運(yùn)行畏邢,但是指針包含另一個(gè)變量的地址,此時(shí)检吆,指針的副本也包含這樣一個(gè)副本
#include<iostream>
#include<string>
#include<iomanip>

using namespace std;

double changeIt(double* pointer_to_it);

int main()
{
    double it{ 15.0 };
    double result{ changeIt(&it) };
    cout << "After function execution, it = " << it << "\n Result returned is " << result << endl;
    return 0;
}

double changeIt(double* pit)
{
    *pit += 10.0;
    cout << "within function, *pit = " << *pit << endl;
    return *pit;
}

給函數(shù)傳送數(shù)組:

給函數(shù)傳送數(shù)組的地址要比傳送數(shù)組更高效舒萎,(不需要復(fù)制許多元素),函數(shù)體中的代碼可以把表示數(shù)組的參數(shù)作為指針來看待蹭沛,即函數(shù)體中可以給數(shù)組參數(shù)使用指針表示法的強(qiáng)大功能

void proj2()
{
    double values[]{ 1.0,2.0,3.00,4.0,5.0,6.0,7.0,8.0,9.0,10.0 };
    cout << "average = " << average(values, size(values)) << endl;
}

double average(double array[], size_t count)
{
    double sum{};
    for (size_t i = 0; i < count; i++)
    {
        sum += array[i];
    }
    return sum / count;
}

注意事項(xiàng):

  • 不能通過size()來避免指定count值逆甜,數(shù)組參數(shù)array只是存儲(chǔ)數(shù)組的地址,并不是數(shù)組本身致板;

  • 如果使用sizeof(array) 將返回?cái)?shù)組地址的內(nèi)存位置的大小交煞,而不是整個(gè)數(shù)組的大小

可以相互使用數(shù)組和指針表示法

double average2(double* array,size_t count)
{
    double sum{};
    for (size_t i = 0; i < count; i++)
    {
        sum += *array++; // 效果一樣
        //sum+= array[i];
    }
    return sum / count;
}

存在誤區(qū):不要向函數(shù)傳遞固定大小的數(shù)組

如果只想計(jì)算10個(gè)數(shù)的平均值,

double average10(double array[10])
{
    double sum{};
    for (size_t i = 0; i < 10; i++)
    {
        sum += array[i];
    }
    return sum / 10;
}

這個(gè)函數(shù)的簽名啊雖然合法斟或,但是呢素征,會(huì)給人一種錯(cuò)誤的期待

編譯器會(huì)強(qiáng)制將剛好包含10個(gè)元素的數(shù)組作為實(shí)參傳遞給該函數(shù)

double average10(double array[10])
double average10(double array[])
double average10(double* array)
//等價(jià)的三種方式
//指定維數(shù)的數(shù)組如果本例中只輸入一個(gè)帶有三個(gè)元素的數(shù)組,那么仍然會(huì)使用10個(gè)去計(jì)算,下標(biāo)會(huì)越界

const 指針參數(shù)

只需要訪問數(shù)組的值御毅,而不需要修改根欧,使用 *const 類型 arrray ** 只讀指針

double average(const double* array,size_t count){}

指定指針為const有兩個(gè)結(jié)果,

  • 編譯器檢查函數(shù)體中的代碼端蛆,確保不會(huì)試圖修改指針?biāo)赶虻闹担ㄗx指針)
  • 允許用指向一個(gè)常量的實(shí)參來調(diào)用函數(shù)

把多維數(shù)組傳給函數(shù)

函數(shù)原型:

 double yield(const double values[][4],size_t n);

最好不要在原型的第一個(gè)緯度上寫數(shù)字凤粗,可以通過編譯器自動(dòng)推斷,但是后續(xù)的緯度必須寫

double yield(const double array[][4], size_t size);
void proj3()
{
    double beans[3][4]{
        {1.0,2.0,3.0,4.0},
        {5.0,6.0,7.0,8.0},
        {9.0,10.0,11.0,12.0} };
    cout << "yield = " << yield(beans, size(beans)) << endl;
}
//多維數(shù)組并不適合使用指針表示法
double yield(const double array[][4], size_t size)
{
    double sum{};
    for (size_t i = 0; i < size; i++)
    {
        for (size_t j = 0; j < std::size(array[i]); j++)
        {
            sum += array[i][j];
        }
    }
    return sum;
}
note:一層數(shù)組不要使用size()今豆,編譯器無法推斷 a[][num]的第一個(gè)維數(shù)嫌拣,因?yàn)樾螀⒅皇潜4媪藬?shù)組的地址,并不知道數(shù)組的緯度情況

按引用傳送

對(duì)應(yīng)與引用參數(shù)的實(shí)參不會(huì)復(fù)制呆躲,引用參數(shù)用實(shí)參初始化异逐,它是調(diào)用函數(shù)中該實(shí)參的別名

eg: 引用string    string&

類型&

  1. 對(duì)于類類型這種,按值傳送實(shí)參和包含因用的函數(shù)傳參是沒有區(qū)別的插掂,但是按值傳送會(huì)對(duì)值進(jìn)行復(fù)制灰瞻,造成內(nèi)存的浪費(fèi)

  2. 對(duì)比引用與指針

    1. 最明顯的區(qū)別:傳送指針的時(shí)候,先使用&獲取一個(gè)值的地址辅甥,而在函數(shù)內(nèi)需要使用*解引用
    2. 指針的鮮明特點(diǎn):可以為nullptr酝润,而引用必須為某個(gè)值。因此允許實(shí)參為null璃弄,就不能使用引用
    3. 使用引用可以寫出更優(yōu)雅的語法袍祖,但是if不看原型,分辨不清是否應(yīng)用了引用谢揪,(和按值傳送的時(shí)候長的一模一樣)
    4. 一般認(rèn)為const int& 比 const int *d更好用

    在使用指針之前必須測(cè)試指針是否為nullptr蕉陋,而引用一般不需要擔(dān)心

  3. 對(duì)比輸入輸出參數(shù)

    note: 一般不要使用 即作為輸入?yún)?shù),又作為輸出參數(shù)的變量

  • 輸入?yún)?shù):一般兩個(gè)選擇:const引用傳送:const string&(建議使用) 按值傳送:string (會(huì)復(fù)制string對(duì)象)
  • 可以將T值傳送給T&和constT&引用拨扶,但是只能將const T 值傳送給const T&引用(當(dāng)然其他也可以傳送給他凳鬓,比如T 表示別名)
  1. 按引用傳送數(shù)組

    優(yōu)點(diǎn):不進(jìn)行復(fù)制。能夠修改原始值

    可以通過傳遞引用向函數(shù)傳遞精確的多維數(shù)組一維的個(gè)數(shù)

    double average10(const double (&array)[10]);
    //此時(shí)可以在函數(shù)中使用size()
    

    note: 關(guān)于引用的隱式轉(zhuǎn)化問題:

    會(huì)有一段臨時(shí)空間實(shí)現(xiàn)相互轉(zhuǎn)換患民,但是double->int時(shí)會(huì)出現(xiàn)丟失缩举,所以會(huì)有報(bào)錯(cuò)

    void double_it(const double& it)
    {//針對(duì)于這種帶const的會(huì)涉及底層轉(zhuǎn)換
     cout<<it<endl;
    }
    
    int age{19};
    double_it(age);//報(bào)錯(cuò)
    

新的const string引用

c++17 #include<string_view>

  1. string_view() 具有常量特性,他只需要指向某個(gè)實(shí)際對(duì)象:string 字符串字面量或其他任何字符數(shù)組中存儲(chǔ)的字符序列匹颤,仅孩,初始化和復(fù)制string_view 的開銷都特別低

  2. 隱式創(chuàng)建string會(huì)復(fù)制字符,但是創(chuàng)建string_view則不會(huì)

    string_view sv{"hjkl"};
    
  3. string_view 不允許直接將其轉(zhuǎn)化為string印蓖,因?yàn)榈讓由婕癱har[]的轉(zhuǎn)化辽慕,必須進(jìn)行強(qiáng)制類型轉(zhuǎn)化

string_view 的幾點(diǎn)注意事項(xiàng):

  • 不完全等同于const string ,沒有提供c_str()來轉(zhuǎn)化為一個(gè)const char* 的數(shù)組赦肃。但是提供了data()函數(shù)溅蛉,于此功能等效
  • 不能使用+運(yùn)算符連接string_view 可以先轉(zhuǎn)化成string再連接eg: string{view};
  • string_view 可以從c樣式的字符數(shù)組創(chuàng)建公浪,大小可以任意大

默認(rèn)實(shí)參值

可在函數(shù)原型中指定默認(rèn)實(shí)參值,但是要按照優(yōu)先級(jí)進(jìn)行指定

void proj4()
{
    showError();
}
void showError(string messages) 
{
    cout << messages << endl; 
}

從函數(shù)中的返回值

可以從函數(shù)中返回任意類型的值船侧。主要討論返回指針和引用中的陷阱

返回指針

在指針返回到調(diào)用函數(shù)的時(shí)欠气,指針指向的變量必須仍然在其作用域中。

警告:不要從函數(shù)返回在棧上分配的自動(dòng)局部變量的地址

  1. 不在調(diào)用程序中的地址
int* larger(int a, int b)
{
    //這些地址不在調(diào)用程序中,所以都是錯(cuò)誤的
    if (a > b)
    {
        return &a;//wrong!
    }
    else
    {
        return &b;//wrong!
    }
}
  1. 在調(diào)用程序中的地址
int* larger(int* a, int* b)//傳來了地址由指針接收
{
    if (*a > *b)
    {
        return a;//來源于調(diào)用程序的地址返回镜撩,是可以的
    }
    else
    {
        return b;//ok
    }
}

一個(gè)案例预柒,求一組數(shù)據(jù)的標(biāo)準(zhǔn)化

在.0-1.0之間的一組數(shù)

步驟:

  • 減去最小值(查找最小值,每個(gè)數(shù)字 - 最小值)

    //查找最小值
    const double* smallest(const double data[], size_t count)//不會(huì)對(duì)最小值進(jìn)行更改袁梗,讀指針
    {//我只是用這個(gè)值而已
      if (count==0)
      {
          return nullptr;
      }
      size_t index_min{};
      for (size_t i = 1; i < count; i++)
      {
          if (data[index_min]>data[i])
          {
              index_min = i;
          }
      }
      return &data[index_min];
    }
    
    //使用最小值宜鸯,調(diào)整數(shù)組
    double* shift_range(double data[], size_t count, double delta)
    {
      for (size_t i = 0; i < count; i++)
      {
          data[i] += delta;
      }
      return data;
    }
    
  • 每個(gè)元素除以max可以將數(shù)組映射到0-1(找到max,除以max)

    //查找最小值
    const double* largest(const double data[], size_t count)//不會(huì)對(duì)最小值進(jìn)行更改围段,讀指針
    {
      if (count == 0)
      {
          return nullptr;
      }
      size_t index_max{};
      for (size_t i = 1; i < count; i++)
      {
          if (data[index_max] < data[i])
          {
              index_max = i;
          }
      }
      return &data[index_max];
    }
    //除以最大值
    double* scale_range(double data[], size_t count, double divisor)
    {
      if (divisor == 0)
      {
          return data;
      }
      for (size_t i = 0; i < count; i++)
      {
          data[i] /= divisor;
      }
      return data;
    }
    
void show_data(const double data[], size_t count = 1, string title = "data values", size_t width = 10, size_t perline = 5);
double* normalize_range(double data[], size_t count);
const double* largest(const double data[], size_t count);//不會(huì)對(duì)最小值進(jìn)行更改,讀指針
const double* smallest(const double data[], size_t count);//不會(huì)對(duì)最小值進(jìn)行更改投放,讀指針
double* scale_range(double data[], size_t count, double divisor);
double* shift_range(double data[], size_t count, double delta);


int* larger(int a, int b);

int main()
{
    //proj1();
    proj2();
    return 0;
}


void proj2()
{
    double samples[]{ 
        11.0,23.0,13.0,4.0,
        57.0,36.0,317.0,88.0,
        9.0,100.,121.0,12.0 };
    const size_t count{ size(samples) };
    show_data(samples,count,"original values");
    normalize_range(samples, count);
    show_data(samples, count, "normalized values", 12);
}

void show_data(const double data[], size_t count, string title, size_t width, size_t perline)
{
    cout << title << endl;
    for (size_t i = 0; i < count; i++)
    {
        cout << setw(width) << data[i];
        if ((i+1)%perline==0)
        {
            cout << '\n';
        }
    }
    cout << endl;
}

const double* largest(const double data[], size_t count);
const double* smallest(const double data[], size_t count);
double* shift_range(double data[], size_t count, double delta);
double* scale_range(double data[], size_t count, double divisior);
double* normalize_range(double data[], size_t count);


//規(guī)范化
double* normalize_range(double data[], size_t count)
{
    return scale_range(shift_range(data, count, -(*smallest(data, count))), count, *largest(data, count));
}


//查找最小值
const double* largest(const double data[], size_t count)//不會(huì)對(duì)最小值進(jìn)行更改奈泪,讀指針
{
    if (count == 0)
    {
        return nullptr;
    }
    size_t index_max{};
    for (size_t i = 1; i < count; i++)
    {
        if (data[index_max] < data[i])
        {
            index_max = i;
        }
    }
    return &data[index_max];
}
//除以最大值
double* scale_range(double data[], size_t count, double divisor)
{
    if (divisor == 0)
    {
        return data;
    }
    for (size_t i = 0; i < count; i++)
    {
        data[i] /= divisor;
    }
    return data;
}
//查找最小值
const double* smallest(const double data[], size_t count)//不會(huì)對(duì)最小值進(jìn)行更改,讀指針
{
    if (count==0)
    {
        return nullptr;
    }
    size_t index_min{};
    for (size_t i = 1; i < count; i++)
    {
        if (data[index_min]>data[i])
        {
            index_min = i;
        }
    }
    return &data[index_min];
}
//使用最小值灸芳,調(diào)整數(shù)組
double* shift_range(double data[], size_t count, double delta)
{
    for (size_t i = 0; i < count; i++)
    {
        data[i] += delta;
    }
    return data;
}

返回引用

  1. 不要從函數(shù)中返回自動(dòng)局部變量的引用

  2. 想要返回對(duì)某個(gè)實(shí)參的非const引用涝桅,就不能把參數(shù)指定為const

  3. 參數(shù)不是const,所以不能把字符串字面量用作實(shí)參烙样,編譯器不允許這么做

  4. 在使用類創(chuàng)建自己的數(shù)據(jù)類型時(shí)冯遂,引用返回類型是必不可少的

返回類型的推斷

  1. 類型推斷可以節(jié)省時(shí)間:return 之后的數(shù)據(jù)類型要明確

  2. auto 不會(huì)推斷為一個(gè)引用類型,而總是推斷為一個(gè)值的類型谒获,即使將一個(gè)引用賦值給auto蛤肌,值也會(huì)被復(fù)制。而且值的這個(gè)副本不是const,除非使用const auto

  3. 要讓編譯器推斷一個(gè)引用類型批狱,可以使用auto& 或const auto&

函數(shù)體中的靜態(tài)變量

函數(shù)體中的靜態(tài)變量在第一次執(zhí)行的 時(shí)候回初始化裸准,后續(xù)調(diào)用的時(shí)候不會(huì)在初始化,而只是進(jìn)行操作赔硫,變量始終存在于程序中炒俱,直到程序結(jié)束

普通變量聲明帶有垃圾值

靜態(tài)變量初始化會(huì)附帶0值

內(nèi)聯(lián)函數(shù)

內(nèi)聯(lián)函數(shù)的定義通常放在頭文件中,該頭文件包含在使用該函數(shù)的每個(gè)源文件中爪膊。即使用該函數(shù)的每個(gè)源文件都應(yīng)該對(duì)其進(jìn)行引用

inline int larger(int m,int n)
{
    return m > n ? m : n ;
}

函數(shù)重載

同名权悟,但是參數(shù)列表不同即可

參數(shù)列表的幾種情況很難判斷

重載和指針參數(shù)

int* 類型處理起來和int[]的參數(shù)類型相同

int* p == int p[];

編譯器會(huì)無視指定數(shù)組維數(shù)的方法,如果需要指定維數(shù)推盛,可以指定array<>或者按照引用傳遞

重載和引用參數(shù)

如下原型

void do_it(stirng number);
void do_it(string& number); 

編譯器表示很懵逼峦阁,do_it(124);到底調(diào)用的是誰?

所以不能根據(jù)type1 和type1& 來區(qū)分?jǐn)?shù)據(jù)類型

note: 臨時(shí)地址可以用{}來初始化const耘成,而不能用{}初始化非const

重載和const參數(shù)

帶有const參數(shù)和沒有const的參數(shù)唯一的區(qū)別就是拇派,為引用定義參數(shù)還是為指針定義參數(shù)

  1. 對(duì)于基本類型 int和const int 是相同的

    //下面兩個(gè)原型沒有區(qū)別
    long larger(long a ,long a);
    long larger(const long a ,const long b);//編譯器會(huì)忽略這個(gè)const
    
  2. 重載和const指針參數(shù)

    1. 在兩個(gè)重載函數(shù)中荷辕,一個(gè)函數(shù)的參數(shù)是type *(會(huì)修改值),另一個(gè)函數(shù)的參數(shù)類型是const type *(一個(gè)只讀指針件豌,不會(huì)修改) 這兩個(gè)函數(shù)是不同的

    2. 編譯器不會(huì)把const值傳送給非const指針參數(shù)的函數(shù)

      const 值會(huì)傳送給const指針

      const int* larger(const int* a,const int* b);
      const int num{0};
      *larger(&num)
      
    3. 一個(gè)函數(shù)的參數(shù)類型是“指向type的指針”疮方,另一個(gè)函數(shù)的參數(shù)類型是“指向type的const指針”

      這兩個(gè)函數(shù)就是相同的

      long* larger(long* const a,long* const b);//常量a指向long類型(不能指向別的了)
      const long* larger(const long* const a,const long* const b);//常量a指向常量的long類型
      
    4. 重載和const引用參數(shù)

      不允許在&后面添加const

      T& (const常量無法賦值給T)和const T&(可以接受const和非const)是不同的

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市茧彤,隨后出現(xiàn)的幾起案子骡显,更是在濱河造成了極大的恐慌,老刑警劉巖曾掂,帶你破解...
    沈念sama閱讀 219,427評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件惫谤,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡珠洗,警方通過查閱死者的電腦和手機(jī)溜歪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來许蓖,“玉大人蝴猪,你說我怎么就攤上這事〔沧Γ” “怎么了自阱?”我有些...
    開封第一講書人閱讀 165,747評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長米酬。 經(jīng)常有香客問我沛豌,道長,這世上最難降的妖魔是什么赃额? 我笑而不...
    開封第一講書人閱讀 58,939評(píng)論 1 295
  • 正文 為了忘掉前任加派,我火速辦了婚禮,結(jié)果婚禮上跳芳,老公的妹妹穿的比我還像新娘哼丈。我一直安慰自己,他們只是感情好筛严,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評(píng)論 6 392
  • 文/花漫 我一把揭開白布醉旦。 她就那樣靜靜地躺著,像睡著了一般桨啃。 火紅的嫁衣襯著肌膚如雪车胡。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,737評(píng)論 1 305
  • 那天照瘾,我揣著相機(jī)與錄音匈棘,去河邊找鬼。 笑死析命,一個(gè)胖子當(dāng)著我的面吹牛主卫,可吹牛的內(nèi)容都是我干的逃默。 我是一名探鬼主播,決...
    沈念sama閱讀 40,448評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼簇搅,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼完域!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起瘩将,我...
    開封第一講書人閱讀 39,352評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤吟税,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后姿现,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體肠仪,經(jīng)...
    沈念sama閱讀 45,834評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評(píng)論 3 338
  • 正文 我和宋清朗相戀三年备典,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了异旧。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,133評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡提佣,死狀恐怖吮蛹,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情镐依,我是刑警寧澤匹涮,帶...
    沈念sama閱讀 35,815評(píng)論 5 346
  • 正文 年R本政府宣布天试,位于F島的核電站槐壳,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏喜每。R本人自食惡果不足惜务唐,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望带兜。 院中可真熱鬧枫笛,春花似錦、人聲如沸刚照。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽无畔。三九已至啊楚,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間浑彰,已是汗流浹背恭理。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評(píng)論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留郭变,地道東北人颜价。 一個(gè)月前我還...
    沈念sama閱讀 48,398評(píng)論 3 373
  • 正文 我出身青樓涯保,卻偏偏與公主長得像,于是被迫代替她去往敵國和親周伦。 傳聞我的和親對(duì)象是個(gè)殘疾皇子夕春,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容