1. 程式人生 > >C++入門基礎筆記

C++入門基礎筆記

.html 編譯器 主函數 block .com type 強制 運算 static

1、C++第一個程序

程序中\nendl相同,endl表示結束流,在流中起做用!

    #include <iostream>
    using namespace std;
    int main()
    {
        cout << "Hello, world!" << endl;
        return 0;
    }

2、註釋

可以通過#if 0#endif來註釋語句通過更改0與1來確定是否使用語句塊

3、數據類型

  1. 修飾符: signed有符號 unsigned無符號 short短的 long長的
  2. 類型:bool布爾型 char
    字符型 int整型 float浮點型 double雙浮點 voidwchar_t寬字符型
  3. 值範圍: float單精度其地址為1位符號,8位指數,23位小數。
    double雙精度是1位符號,11位指數,52位小數。char八位字節

typedef 聲明

extern聲明變量應放在main()前面,
extern可以置於變量或者函數前,以標示變量或者函數的定義在別的文件中,提示編譯器遇到此變量和函數時在其他模塊中尋找其定義。另外,extern也可用來進行鏈接指定。

extern int c;

enumeration 枚舉型

enum color { red, green, blue } c;
c = blue;

默認情況下red的值為0,green為1,以此類推但當:

enum color { red, green=5, blue };

這個情況下時red的值為0,green為5,blue為6.


4、全局變量

全局變量放在mian()前面,所以程序都可以訪問,在程序中,局部變量和全局變量的名稱可以相同,但是在函數內,局部變量的值會覆蓋全局變量的值。局部變量被定義時,系統不會對其初始化,您必須自行對其初始化.全局會自動初始化
int0 char"\0" float0 double0 pointerNULL

常量

  • 整數常量可以帶一個後綴,後綴是 U 和 L 的組合,U 表示無符號整數(unsigned),L 表示長整數(long)。

  • 浮點常量當使用指數形式表示時, 必須包含小數點、指數,或同時包含兩者。帶符號的指數是用 e 或 E 引入的。通過使用後綴 f 或 l常量可以分別指定為 float 或 long double

    18.46e0      // 18.46
    18.46e1      // 184.6
  • 字符常量

    `\` 轉義符 
    `\a`     警報鈴聲 
    `\b`    退格鍵
    `\f`    換頁符
    `\n`    換行符
    `\r`    回車
    `\t`    水平制表符
    `\v`    垂直制表符
    `\ooo`  一到三位的八進制數
    `\xhh...`   一個或多個數字的十六進制數

    定義常量

    #define 預處理器

    \#define LENGTH 10

    const前綴聲明指定類型的常量

    常量不能更新

    const int  LENGTH = 10;

修飾符類型

explicit構造函數用於防止隱式調用!

存儲類

  • register 存儲類 用於定義存儲在寄存器中而不是 RAM 中的局部變量。不能對它應用&
  • static 存儲類 指示編譯器在程序的生命周期內保持局部變量的存在.
    即在函數中static int i = 5;局部靜態變量 重復調用函數時還能再訪問i
  • extern 存儲類 在子文件中聲明已存在一個已定義的變量或函數的引用
  • mutable 存儲類 後面講解
  • thread_local 存儲類 聲明的變量僅可在它在其上創建的線程上訪問.變量在創建線程時創建,並在銷毀線程時銷毀。 每個線程都有其自己的變量副本。可以與 static 或 extern 合並。僅應用於數據聲明和定義,不能用於函數聲明或定義。

    thread_local int x;
    class X
    {
    static thread_local std::string s; 
    };
    static thread_local std::string X::s; 
    void foo()
    {
    thread_local std::vector<int> v; 
    }

運算符

  • 算術運算符

    % 取余運算

  • 關系運算符
  • 邏輯運算符

    && 與(並且) 邏輯與 AND
    ||(或) 邏輯或 OR
    !(非)

  • 位運算符

    A = 0011 1100 B = 0000 1101
    & 二邊為真才為真 ,A&B = 0000 1100 位與 AND
    | 有一個為真即真 ,A|B = 0011 1101 位或 OR
    ^ 二邊不一樣的真 ,A^B = 0011 0001 位異或 XOR
    ~ 取反相, ~A = 1100 0011

  • 賦值運算符

    C += A//相當於 C = C + A
    C -= A//相當於 C = C - A
    C *= A//相當於 C = C * A
    C /= A//相當於 C = C / A
    C %= A//相當於 C = C % A
    C <<= 2//等同於 C = C << 2
    C >>= 2//等同於 C = C >> 2
    C &= 2//等同於 C = C & 2
    C ^= 2//等同於 C = C ^ 2
    C |= 2//等同於 C = C | 2
  • 雜項運算符

    sizeof 返回變量的大小,字節數如sizeof(int),返回4

    x = (y < 10) ? 30 : 40; 當Y=10時,X取40 相當於if語句

    .點運算符與->箭頭運算符 箭頭操作符是結構體 或者 對象 指針用來訪問其對象 或者 對象成員時用的符號比如struct aaa{int a,int b;};class bb{int a;int b‘;void test()};當我們定義一個結構體變量的時候比如 aaa t; bb t;往往是通過.符號來獲得或者訪問其中的成員變量 或者函數如 t.a t.b t.test()但是 如果我們定義的是一個結構體指針aaa t;bb t那麽就需要用箭頭符號來訪問了t->a t->b t->test()這麽講你明白了嗎

    強制轉換運算符 把一種數據類型轉換為另一種數據類型。
    int(2.2000) 將返回 2。

    指針運算符 & 返回變量的地址。例如 &a; 將給出變量的實際地址。

    指針運算符 * 指向一個變量。例如,*var; 將指向變量 var。


循環

循環類型

  • while(表達式){};
  • for(初始化,表達式,i++){};
  • do{...}while(表達式);

    循環控制

  • break跳出(中斷)循環體
  • continue跳出本次循環(不中斷)
  • goto轉移到被標記,(不建議使用)

    函數

    函數參數

  • 傳值調用--oid swap(int x, int y)調用時 swap(a, b);
  • 指針調用--void swap(int *x, int *y)調用時swap(&a, &b);
  • 引用調用--swap(int &x, int &y)調用時swap(a, b);

    數字

    數學運算

  1. double cos(double);該函數返回弧度角(double 型)的余弦。
  2. double sin(double);該函數返回弧度角(double 型)的正弦。
  3. double tan(double);該函數返回弧度角(double 型)的正切。
  4. double log(double);該函數返回參數的自然對數。
  5. double pow(double, double);假設第一個參數為 x,第二個參數為 y,則該函數返回 x 的 y 次方。
  6. double hypot(double, double);該函數返回兩個參數的平方總和的平方根,也就是說,參數為一個直角三角形的兩個直角邊,函數會返回斜邊的長度。
  7. double sqrt(double);該函數返回參數的平方根。
  8. int abs(int);該函數返回整數的絕對值。
  9. double fabs(double);該函數返回任意一個十進制數的絕對值。
  10. double floor(double);該函數返回一個小於或等於傳入參數的最大整數。

    數組

    double balance[] = {1000.0, 2.0, 3.4, 7.0, 50.0};
    double salary = balance[9];
    int a[3][4] = {{0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11}};//多維數組

    指向數組的指針

    double *p;
    double balance[10];
    p = balance;

    使用數組名作為常量指針是合法的,反之亦然。因此,*(balance + 4) 是一種訪問 balance[4] 數據的合法方式。一旦您把第一個元素的地址存儲在 p 中,您就可以使用 *p*(p+1)*(p+2) 等來訪問數組元素。

    傳遞數組給函數

    從函數返回數組

    C++ 不允許返回一個完整的數組作為函數的參數。但是,您可以通過指定不帶索引的數組名來返回一個指向數組的指針。如果您想要從函數返回一個一維數組,您必須聲明一個返回指針的函數,如下:

\#include <iostream>
\#include <cstdlib>
\#include <ctime> 
using namespace std; 
// 要生成和返回隨機數的函數
int * getRandom( )
{
  static int  r[10]; 
  // 設置種子
  srand( (unsigned)time( NULL ) );
  for (int i = 0; i < 10; ++i)
  {
    r[i] = rand();
    cout << r[i] << endl;
  } 
  return r;
} 
// 要調用上面定義函數的主函數
int main ()
{
   // 一個指向整數的指針
   int *p; 
   p = getRandom();
   for ( int i = 0; i < 10; i++ )
   {
       cout << "*(p + " << i << ") : ";
       cout << *(p + i) << endl;
   } 
   return 0;
}

字符串

字符

char greeting[6] = {‘H‘, ‘e‘, ‘l‘, ‘l‘, ‘o‘, \0};//字符組
cout << greeting << endl; //輸出
  1. strcpy(s1, s2);復制字符串 s2 到字符串 s1。
  2. strcat(s1, s2);連接字符串 s2 到字符串 s1 的末尾。
  3. strlen(s1);返回字符串 s1 的長度。
  4. strcmp(s1, s2);如果 s1 和 s2 是相同的,則返回 0;如果 s1
  5. strchr(s1, ch);返回一個指針,指向字符串 s1 中字符 ch 的第一次出現的位置。
  6. strstr(s1, s2);返回一個指針,指向字符串 s1 中字符串 s2 的第一次出現的位置。

String類

string str1 = "Hello";
str1.size();//返回長度

指針

指針可以理解為是一個變量,但這變量只存儲地址信息,地址

int var = 20;// 實際變量的聲明
int *ip;// 指針變量的聲明
ip = &var;// 在指針變量中存儲 var 的地址

空指針

int *ptr = NULL;空指針,其地址值為0,空指針中不允許訪問地址為 0 的內存,
所以cout <<"ptr的值" <<*ptr;會報錯,應先if(ptr)判斷

指針數組

\#include <iostream>
using namespace std;
const int MAX = 3;
int main ()
{
   int  var[MAX] = {10, 100, 200};
   int *ptr[MAX];  //指針數組
   for (int i = 0; i < MAX; i++)
   {
      ptr[i] = &var[i]; // 賦值為整數的地址
   }
   for (int i = 0; i < MAX; i++)
   {
      cout << "Value of var[" << i << "] = ";
      cout << *ptr[i] << endl;
   }
   return 0;
}

指向指針的指針(多級間接尋址)

   int  var;
   int  *ptr;
   int  **pptr;
   var = 3000;   
   ptr = &var;// 獲取 var 的地址   
   pptr = &ptr;// 使用運算符 & 獲取 ptr 的地址

傳遞指針給函數

 getSeconds( &sec );//調用時
void getSeconds(unsigned long *par)
{
   // 獲取當前的秒數
   *par = time( NULL );
   return;
}
getAverage( balance, 5 );
double getAverage(int *arr, int size)
{
//...
}

從函數返回指針

C++ 不支持在函數外返回局部變量的地址,除非定義局部變量為 static 變量。

int * myFunction()
{
}
//調用
int *p; 
p = getRandom();

引用

其與直接使用參數的區別在於,不用開辟一塊內存,進行賦值拷貝動作。(可以理解這是一個另名)

把引用作為參數

void swap(int& x, int& y);
int main ()
{
   int a = 100;
   int b = 200;   
   swap(a, b);// 調用函數來交換值
   return 0;
}
void swap(int& x, int& y)
{
   int temp;
   temp = x; /* 保存地址 x 的值 */
   x = y;    /* 把 y 賦值給 x */
   y = temp; /* 把 x 賦值給 y  */  
   return;
}

把引用作為返回值

double vals[] = {10.1, 12.6, 33.1, 24.1, 50.0};
double& setValues( int i )
{
  return vals[i];   // 返回第 i 個元素的引用
}
int main ()
{
setValues(1) = 20.23; // 改變第 2 個元素
setValues(3) = 70.8;  // 改變第 4 個元素
}

註意:1.不能返回局部變量的引用。2.不能返回函數內部new分配的內存的引用 3.可以返回類成員的引用,但最好是const。


日期與時間

程序中引用 <ctime> 頭文件。

struct tm {  //結構體
  int tm_sec;   // 秒,正常範圍從 0 到 59,但允許至 61
  int tm_min;   // 分,範圍從 0 到 59
  int tm_hour;  // 小時,範圍從 0 到 23
  int tm_mday;  // 一月中的第幾天,範圍從 1 到 31
  int tm_mon;   // 月,範圍從 0 到 11
  int tm_year;  // 自 1900 年起的年數
  int tm_wday;  // 一周中的第幾天,範圍從 0 到 6,從星期日算起
  int tm_yday;  // 一年中的第幾天,範圍從 0 到 365,從 1 月 1 日算起
  int tm_isdst; // 夏令時
}

示例

\#include <stdio.h>
\#include <time.h>
int main ()
{
   clock_t start_t, end_t;
   double total_t;
   start_t = clock();//clock_t clock(void)返回程序執行起(一般為程序的開頭)處理器時鐘所使用的時間
   time_t rawtime;
   struct tm *info; //結構體tm
   char buffer[80];
   time( &rawtime );//返回系統的當前自 1970 年 1 月 1 日以來經過的秒數
   info = localtime( &rawtime );//使用 timer 的值來填充 tm 結構
   printf("當前的本地時間和日期:%s", asctime(info));
   end_t = clock();
   total_t = (double)(end_t - start_t) / CLOCKS_PER_SEC;//CLOCKS_PER_SEC是標準c的time.h頭函數中宏定義的一個常數,表示一秒鐘內CPU運行的時鐘周期數,用於將clock()函數的結果轉化為以秒為單位的量
   printf("CPU 占用的總時間:%f\n", total_t  );
   return(0);
}

基本輸入輸出

  • cout 輸出 cout <<"test"<<endl;
  • cin 輸入 cin >> name;
  • cerr 錯誤流 cerr << "test" << endl;
  • clog 日誌流 clog << "test" << endl;

數據結構

strcpy(str1,str2);把str2的字符串數據復制到str1中!

指向結構的指針

printBook( &Book1 );//main調用
void printBook( struct Books *book )
{
   cout << "書標題  : " << book->title <<endl;
   cout << "書作者 : " << book->author <<endl;
   cout << "書類目 : " << book->subject <<endl;
   cout << "書 ID : " << book->book_id <<endl;
}

類&對象

類定義

\#include <iostream>
using namespace std;
class Box
{
   public:
      double length;   // 盒子的長度
      double breadth;  // 盒子的寬度
      double height;   // 盒子的高度
      double getVolume(void);// 返回體積
};
double Box::getVolume(void)  //範圍解析運算符::定義該函數
{
    return length * breadth * height;
}
int main()
{
Box Box1;
double volume = 0.0;// 用於存儲體積 
Box1.length=6; 
Box1.breadth=7;
Box1.height=5;
volume = Box1.getVolume();
  cout << "Box1 的體積:" << volume <<endl;
return 0;
}
}

繼承

格式

class Rectangle: public Shape{}Shape為基類

多繼承

class <派生類名>:<繼承方式1><基類名1>,<繼承方式2><基類名2>,…{<派生類類體>};

虛繼承

格式:class 類名: virtual 繼承方式 父類名

  • 舉例來說:假如類A和類B是由類X繼承而來(非虛繼承且假設類X包含一些成員),且類C同時繼承了類A和B,那麽C就會擁有兩套和X相關的成員(可分別獨立訪問,一般要用適當的消歧義修飾符)。但是如果類A虛繼承自類X,那麽C將會只包含一組類X的成員數據。

重載運算符和重載函數

重載函數

class printData 
{
   public:
      void print(int i) {
        cout << "整數為: " << i << endl;
      } 
      void print(double  f) {
        cout << "浮點數為: " << f << endl;
      }
};

運算符重載

      // 重載 + 運算符,用於把兩個 Box 對象相加
      Box operator+(const Box& b)
      {
         Box box;
         box.length = this->length + b.length;
         return box; //返回box
      }
     // 重載小於運算符( < )
      bool operator <(const Distance& d)
      {
         if(feet < d.feet)
         {
            return true;
         }
         if(feet == d.feet && inches < d.inches)
         {
            return true;
         }
         return false;
      }
      //重載輸出      
     friend ostream &operator<<( ostream &output, 
                                       const Distance &D )
      { 
         output << "F : " << D.feet << " I : " << D.inches;
         return output;            
      }
      //重載輸入 
      friend istream &operator>>( istream  &input, Distance &D )
      { 
         input >> D.feet >> D.inches;
         return input;            
      }

其它重載請查看 菜鳥教程

C++入門基礎筆記