1. 程式人生 > >關於C++的那些事兒(一)--讀《寫給大忙人看的C++》

關於C++的那些事兒(一)--讀《寫給大忙人看的C++》

註釋的使用
  1. /* / 是從一個(/ )開始到 ( */)結束的。
  2. 重置輸入流的錯誤標誌,需要呼叫cin.clear()。
  3. int x=static_cast(0.0); ==型別轉換==
  4. 從不建議在表示式中組合==有==符號整數和無符號整數。因為無符號整數unsigned int x=-1;在輸出的時候會變成65535,因為-1的二進位制是全1。
  5. wchat_c wide_str[]=L”\x10ff”; 兩個位元組的十六進位制必須用寬字元。
  6. R “C:\windows” 在C++11中可以原樣輸出反斜線。
  7. decltype來確定表示式的型別,e.g. decltype(x+y) z=0;
  8. typeid是C++的關鍵字之一,等同於sizeof這類的操作符。
int x=0;
if(typeid(x+x)==typeid(int)){
    cout<<12<<endl;
   } 
  1. & 按位與  | 按位或  ^按位異或
  2. 字首遞增是應當鼓勵的,因為字尾遞增需要建立被遞增的物件的副本。
++n; //單獨的字首遞增 
n++; //單獨的字尾遞增
  1. << 和 >>都補得是0。
  2. C++的型別轉換運算子
運算子 描述
static_cast 將資料轉換為指定型別。這是一個簡單的資料轉換,不涉及指標或const屬性
reinterpret_cast 將一個指標轉換為一個不同的基本型別
const_cast 可用於從表示式中移除const屬性,使得const指標可以被賦值給一個非const指標
dynamic_cast 允許你通過一個類層次結構向下投,但前提是表示式實際上指向所涉及的型別
(型別)表示式 C語言的型別轉換,用於支援向後相容,但正是的話不鼓勵這麼做

13. C++11中,基於範圍的for語句。

//可以訪問但不能修改
for(int i:array){
    cout<< i <<endl;
}
//可以訪問,也可以修改
for(int &i:array
){ i=0; }

14.異常處理

C++庫中定義的基本異常類

異常 說明
std::exception 所有C++異常的基類。你可以呼叫what()方法來獲取描述該異常的C字串,該方法被所有子類繼承。
std::logic_error 從exception中派生。其中大部分是庫函式,或操作符函式可能丟擲但沒有由編譯器本身捕獲的錯誤。
std::runtime_error 從exception中派生。這個類包括常用的執行時錯誤。

邏輯錯誤異常

異常 說明
std::bad_cast 報告dynamic_cast表示式的無效使用
std::bad_typeid 報告在某個物件上使用typeid操作符,結果有一個void型別的情況。
std::domain_error
std::invalid_argument
std::length_error
std:: out_of_range

15. break 只退出當前迴圈,如巢狀迴圈,可通過設定標記使外側while迴圈達到推出條件。
16. lambda 函式

//lambda in STL
#include <algorithm> 
int arr[5]={5,10,15,20,25};
int sum=0;
for_each(arr,arr+5,[&sum] (int n) {sum+=n;})

//按值捕獲的只會捕獲一次。
int i =10;
auto f=[ i ](int n ){return n>i;};
cout<<"Is 5>i?"<<f(5)<<endl;//print false(0)
i=1;
cout<<"Is 5>i?"<<f(5)<<endl;//print false(0)
//[&] 
int i =10;
auto f=[ &i ](int n ){return n>i;};
cout<<"Is 5>i?"<<f(5)<<endl;//print false(0)
i=1;
cout<<"Is 5>i?"<<f(5)<<endl;//print true(1)

//返回一個lambda的函式
#include<functional>
#include <iostream>
using namespace std;
function<int(int,int)> get_fun(){
    int n=10;
    return [n](int a,int b){return a+b+n;};
    //[&n] 會導致垃圾指標,因為n是區域性非靜態變數。
}
int main(){
    auto f = get_fun();
    cout<<f(1,2)<<endl;//print 13
}
  1. constexpr關鍵字應用於函式時,會使編譯器儘可能把對該函式的呼叫當作編譯時常量。
int &j=i;//j是 i 的別名。

void funtion(const int &a);//儘量把引用引數宣告為 const 型別。
  1. 關於陣列
int array1[10]={};//把元素都初始化為0. 假設只有{1}只給第一個元素賦值。
int array2[10];//如果這是區域性變數,則元素包含垃圾,此刻的垃圾指的是隨機的無意義的值。

在C++11中,基於範圍的for只能與全域性陣列連用,因為他們的長度是已知的,不能用在函式中。

int i=0;
for(auto &x:arr){
    x=i++;//為陣列arr賦值1,2,3,.......
}

字尾自增運算子(++)比 “at” 運算子(*)具有更高的優先順序。

*P++=0;//等同於
*(p++)=0; //先賦值在自增
//對於一個拷貝函式
//指標版
void copy_array(int *p1,int *p2,int n){
    for(int i=0;i<n;i++){
        *p1++ = *p2++;
    }
}
//陣列索引版
void copy_array(int *p1,int *p2,int n){
    for(int i=0;i<n;i++){
        p1[i] = p2[i];
    }
}

指標版更 有效,因為它避免了陣列索引版不得不反覆計算索引並和重新計算元素位置的操作。(指標版只在順序訪問有效,隨機訪問不節省,也就是當我們要遍歷的時候選擇指標版

在多維的情況下,指標版的增益很顯著。

double array_2D[10][10];
reset_2D_dbl_array(array_2D,10,10);
//對於array_2D[10][10]陣列傳遞失敗  型別不匹配
void reset_2D_dbl_array(double **p,int numberOfRows,int numberOfColumns){
    int n = numberOfRows * numberOfColumns;
    while(n-- > 0){
        **p++ = 0.0;
    }
} 

----變成一維陣列來算
void reset_2D_dbl_array_P(double *p,int numberOfRows,int numberOfColumns){
    int n = numberOfRows * numberOfColumns;
    while(n-- > 0){
        *p++ = 0.0;
    }
}
void reset_2D_dbl_array(double p[][10],int numberOfRows,int numberOfColumns){
    for(int i=0;i < numberOfRows;i++){
        for(int j=0; j < numberOfColumns; j++){
            p[i][j]=i*j;
        }
    }
}

int a[2][3]; int**p=&a; //這裡我用&a來賦值行不行呢。是不行的。 這裡為什麼是錯誤的,原因就是因為&a的型別不是int**型別。所以型別不相容,導致不能賦值,同時這兩種型別是不可以相互轉換的。 那麼&a到底是一個什麼樣的型別呢。 我們說&a去的是整個陣列的地址,那麼&a自然就是指向整個陣列的指標了。 int (*p)[2][3]=&a; 此時這樣賦值才是正確的。如果我們要用a直接賦值,那該定義一個什麼樣的變數來接受它呢,首先要明白,陣列名代表的地址型別是指向陣列的第一個元素的指標,例如: int a[10]; int *p=a; 實際上這裡與 int *p=&a[0];是等價的。因為指向a[0]的指標型別就是int*型別。 那麼&a的是去陣列的地址,其型別是指向陣列的指標,而不是指向陣列第一個元素的指標,整個是要區別的,他們的型別就不一樣。 int(*p)[10]=&a; 所以說這裡的a和&a絕對不是同一個東西,雖然本質上他們的地址值是一樣的,但是他們的型別不一樣。就決定他們代表不同的意義。 那麼剛剛說了對於下面的例子: int a[2][3]; int (*p)[2][3]=&a; // 我們可以定義這樣的一個變數p來接受&a的值。 那麼我們要接受a應該定義一個什麼樣的變數呢。a[2][3]是一個二維陣列,可以看成是這樣的a是一個數組,具有兩個元素,分別為a[0],a[1]其中這兩個元素的值a[0],a[1]他們的值又是一個具有3個元素的陣列。此時我們可以將a[0],a[1]看成是陣列名,那麼a[0][0]就是陣列a[0]的第0個元素了。對應關係如下: a[0] —-> a[0][0],a[0][1],a[0][2] a[1] —-> a[1][0],a[1][1],a[1][2] 那麼a到底是什麼,其實a陣列有兩個元素,a[0],a[1],那麼a的值自然就是其第一個元素的地址了,也就是&a[0]了。這是一個什麼型別? 我們知道如果我們將a[0]看成一個整體,例如我們用A來代替a[0],那麼A[0],A[1]就相當於a[0][0],a[0][1] 。 此時A就是一個int型別的陣列,&A,的型別實際上就是 int(*p)[3]這個型別。 所以下面的程式碼也是正確的: int a[2][3]; int(*p)[3]=a;
閱讀原文

19.

 void set_array(double arr[],int n){
     double *p=arr;
     while(n-- >0){
        *p++=1.0;
     }
 }
 void set_array_P(double *arr,int n){
      for(int i=0;i < 10;i++){
        arr[i]=1.0;
    }
 }
 //也可以
 void set_array_P(double arr[],int n){
      for(int i=0;i < 10;i++){
        arr[i]=1.0;
    }
 }
 //陣列用指標來操作,或者直接傳遞可操作型別的
double array1[10];
set_array(array1,10);
set_array1(array1,10);
// 對於不需要修改的傳遞可以用const修飾
//const修飾的可以接收const和非const型別的值,反之不可。
void display(const double arr[],int n){
        for(int i=0;i < 10;i++){
         cout<< arr[i];
    }
 }
  1. [const] 型別 * [const] 變數名
    第一個const指定基本型別是常量,第二個const保護指標免受更改。

  2. 資料宣告— 宣告變數的更完整的語法是\
    [修飾符] 型別 變數宣告  

  3. void指標

適用於void*指標的規則如下
- 你可以把任意地址賦值給一個void*指標或一個void*指標引數。
- 但是,你不能反方向取值,一個void*不能不經過轉換型別就賦值給具體型別的指標。
- 如果對一個void*地址進行指標運算,則不執行按比例放大。

int integer = *(reinterpret_cast<const int*>(p1));//p1 是 void* 型別的

23.指標函式

typedef int (* FPTR)(int);
int fun(int n){
    return n*2;
}
FPTR getFunction(){
    return fun;
}
 int main()
{
   FPTR fp = getFunction();
   cout<<(fp)(10);//print 20

    return 0;
} 
  1. 智慧指標

包含這個標頭檔案

智慧指標型別 說明
shared_ptr 共同擁有一個記憶體資源,在內部保持一個引用計數,並且僅當資源的引用計數變為0時才能被刪除。不能被用於指向陣列。
unique_ptr 擁有一個不可以與另一個指標共享的記憶體資源。指標一旦被刪除,該資源就被刪除,次指標型別可以用於動態建立的陣列。
weak_ptr 類似於shared_ptr,但他不增加或減少記憶體資源的引用計數。

- 共享指標.reset();刪除共享指標與當前指向記憶體物件之間的關聯。
- 共享指標.reset(新指標);刪除共享指標與當前指向記憶體物件之間的關聯。

//埃拉托色尼篩
#include <iostream>
#include <math.h>
using namespace std;
void process_prime(bool *p,int max_n, int n);
void display(bool *p,int max_n);
 int main()
{
   int max_n=0;
   cout<<"Calculate primes up to what number?\n";//計算質數到什麼數?
   cin>>max_n;
   bool *p = new bool[max_n + 1];//分配陣列
   for(int i=2;i<max_n;i++){//初始化陣列
        p[i]=true;
   }
   for(int i=2;i<sqrt(max_n);i++){//查詢質數   //查到平方根就夠了
        if(p[i]){
            process_prime(p,max_n,i);
        }
   }
   display(p,max_n);//print
   cout<<endl;
   delete [] p;//不是絕對必要的,但卻是一個好主意。
   cin.ignore();//
    return 0;
}
/* 處理質數函式
列印傳遞給函式的數n,然後把布林陣列(p)的所有元素中,
對應於n的倍數的元素被標記為false。  */
void process_prime(bool *p,int max_n, int n){
    for(int i=n+n;i<=max_n;i+=n){
        p[i]=false;
    }
}
//輸出結果
void display(bool *p,int max_n){
    for(int i=2;i<max_n;i++){
        if(p[i]){
            cout<<i<<"\t";
        }
   }
}

相關推薦

關於C++的那些事兒--大忙人C++》

註釋的使用 /* / 是從一個(/ )開始到 ( */)結束的。 重置輸入流的錯誤標誌,需要呼叫cin.clear()。 int x=static_cast(0.0); ==型別轉換== 從不建議在表示式中組合==有==符號整數和無符號整數。因為無符號整數u

C#依賴注入那些事兒

1 IGame遊戲公司的故事 1.1 討論會 話說有一個叫IGame的遊戲公司,正在開發一款ARPG遊戲(動作&角色扮演類遊戲,如魔獸世界、夢幻西遊這一類的遊戲)。一般這類遊戲都有一個基本的功能,就是打怪(玩家攻擊怪物,藉此獲得經驗、虛擬貨幣和虛擬裝備

關於搶火車票的那些事兒

關於搶火車票的那些事兒(一) 又到了年底了,沒到這個時候外出工作的人兒又開始犯愁了火車票的事兒~ 票不好買,於是黃牛呀,各種搶票軟體走進了大家的事業。 搶票軟體到底是怎麼做的呢? 正好最近工作不忙,我也比較感興趣,那就來探究一下。

DeepFM演算法解析及Python實現 FFM演算法解析及Python實現 FM演算法解析及Python實現 詞嵌入的那些事兒

1. DeepFM演算法的提出 由於DeepFM演算法有效的結合了因子分解機與神經網路在特徵學習中的優點:同時提取到低階組合特徵與高階組合特徵,所以越來越被廣泛使用。 在DeepFM中,FM演算法負責對一階特徵以及由一階特徵兩兩組合而成的二階特徵進行特徵的提取;DNN演算法負責對由輸入的一階特徵進行全連線

移動端那些事兒移動端開發注意事項

對於手機網站建設,總結了如下幾點注意: 1、 安卓瀏覽器看背景圖片,有些裝置會模糊。 用同等比例的圖片在PC機上很清楚,但是手機上很模糊,原因是什麼呢? 經過研究,是devicePixelRatio作怪,因為手機解析度太小,如果按照解析度來顯示網頁,這樣字會非常小,所以蘋果當初就把iPhone 4的9

【JAVA秒會技術之玩轉多執行緒】多執行緒那些事兒

多執行緒那些事兒(一) 現在只要出去面試,關於“Java多執行緒”的問題,幾乎沒有一家單位不問的,可見其重要性。於是博主抽空研究了一下,確實很有意思!以下是我綜合整理了網上的各種資料,和個人的一些理解,寫的一篇總結博文,僅供學習、交流。 (一)多執行緒的概念      

網路中的那些事兒之神奇的通訊

       考試大戰在即,這是大二生涯中最後一場戰役,為了給自己這半年的戎馬生涯畫上一個圓滿句號,故最近幾天在複習(其實說預習更為合理一些)《計算機網路》這門課程。臨時抱佛腳,真心地不好。不過好在自

EditText 的那些事兒

針對EditText 的相關知識點整理一下,主要有EditText的相關屬性,EditText的自定義VIew方面以及連帶的其他知識點;一為EditText的相關屬性及連帶知識點,後面寫寫自定義view繼承EditText, 比如密碼輸入框(帶刪除,明文暗文按鈕),更強大的autoCompl

計算機中那些事兒:妙用遠端,方便你我他!

你還在為忘記電腦關機,傳檔案忘帶u盤,急著操作電腦而不在電腦旁,,,而苦惱嗎??? 如果是,那恭喜您,以下的方法一定會接觸您的煩惱!如果不是,那也恭喜您,一起下去看看吧下面的內容一定會讓您解除將來的煩

鄧仰東專欄|機器學習的那些事兒

目錄 1.緒論 1.1.概述 1.2 機器學習簡史 1.3 機器學習改變世界:基於GPU的機器學習例項      1.3.1 基於深度神經網路的視覺識別      1.3.2 AlphaGO      1.3.3 IBM Waston 1.4 機器學習方

關於androidstudio cmake那些事兒

關於在as上使用cmake開發NDK,還沒有比較詳細統一的資料,就個人踩過的一些坑記一下,我們在android NDK開發的時候大部分是在windows下面進行開發,在windows下面編譯用標準c++庫的一些檔案,然後又要編譯成so的時候,這個時候就比較坑了。

Shiro那些事兒: Shiro初探

 引言   許可權,可以簡單的理解成你能幹什麼,不能幹什麼。在管理系統中,對許可權的設計可以很簡單,也可以很複雜。簡單點的,基本都是基於角色扮演的方式,比如系統管理員角色可以操作哪些選單,普通使用者角色可以操作哪些選單等等,通過讓不同使用者扮演不同的角色,不同角色授予不同的選單許可權,來實現對訪問使

Objective C 學習心得 :--Windows下搭建objective C開發環境

      最近打算針對iPhone、iPod touch和iPad開發一些應用,所以,需要開始學習Objective C(蘋果推出的類似C語言的開發語言)。由於蘋果的自我封閉的產業鏈發展模式(從晶片、機器、開發語言、終端產品、服務)的限制,要想開發針對蘋果iPhone等產品

C++數值與字串相互轉換的那些字串轉數值(轉載請註明)

以前一門心思搞演算法,這個東西覺得自己寫個函式就能實現的事,但是到了公司後才發現同事寫的程式碼裡面,呼叫各種庫函式、window API、流來實現。什麼都不懂的我表示鴨梨很大,今天翻了翻資料瞭解了下各種方法的使用方法、區別以及適用範圍,寫成了這篇又長又臭又沒條理的東西。 注

計算機中那些事兒:讓你的計算機飛般的感覺

  【前言】     在當今這個IT時代(當然正向 DT時代過渡)計算機已經成為人們的必備物品之一。正所謂:工欲善其事必先利其器。今天咱們就一起來聊聊如何讓咱們的電腦有飛一般的感覺。 【我記憶

Objective-C語法之第一個iPhone應用程式的那些事兒

#import "HelloWorldViewController.h" @implementation HelloWorldViewController - (void)didReceiveMemoryWarning { // Releases the view if it doesn't ha

前端同學的C++入門教程:概述和環境搭建

說明:本人是前端er,因為最近對 UE4(一個遊戲開發引擎)產生了興趣,而這個引擎源開發遊戲時需要用到 C++ ,所以就開始入坑 C++ 了。現將自己學習 C++ 的筆記整理並分享出來,以便一些想入門 C++ 的朋友一起學習,將會以系列教程的的形式來編寫,這是第一篇。 ## C++ 是什麼? 我們都知道,目

c# 進程

for 定義 blog 調用 image method 程序 leg pri 1、進程,進程和多線程的概念: 進程:一個程序運行時所有資源的統稱。 線程:每一個響應執行流就是線程。(做不同的事情) 多線程:多個線程同時工作 2、同步和異步的概念: 同步:前面的先執行,後面的

html頁面中拍照和上傳照片那些事兒

read itl 加載完成 大小 上傳照片 那些事 cnblogs 設置 新建 本文為原創,轉載請註明出處: cnzt 文章:cnzt-p http://www.cnblogs.com/zt-blog/p/6895352.html 本文主要說下iOS上

軟件project—思考項目開發那些

app 爛代碼 fontsize 模式 大型 不明確 極限 後拋 con 閱讀文件夾: 1.背景2.項目管理,質量、度量、進度3.軟件開發是一種設計活動而不是建築活動4.高速開發(簡單的系統結構與復雜的業務模型)5.技術人員的業務理解與產品經理的業務理解的終於業務模型