1-23 彙總前面的學習經驗(第四章、第五章)(壹)

第四章  數組和指針

1、類似於vector和iterator高級符合類型,數組和指針是低級符合類型。數組不允許添加元素,指針則可以像迭代器遍歷和檢查數組中的元素;

      數組無法進行size、push_back等操作

      數組是由類型名、標識符和尾數組成的複合數據類型

2、vector 使用 vector::size_type 作爲下標的類型,而數組下標的正確類型則是 size_t(size_t爲bitset.size()返回二進制位的個數,)

       數組的維數必須用值大於等於1的常量表達式定義:整型字面值常量、枚舉常量、常量表達式初始化的整型const對象(非const變量以及到運行階段才知道其值的const變量都是非法的)

        內置類型初始化爲0,若是類類型則調用該類的默認構造函數進行初始化。

    字符數組的兩種表達方式:

char ca1[] = {'C', '+', '+'};              // no null維數3
char ca2[] = {'C', '+', '+', '\0'};        // explicit null維數4
char ca3[] = "C++";                        // null terminator added automatically 維數4
                                           // null作爲空字符用於結束字符串

3、數組的長度是固定的,區別於vector類型,數組不提供push_back或者其他的操作在數組中添加新元素。管理好內存很關鍵。

     導致安全問題的最常見原因是所謂“緩衝區溢出(buffer overflow)”錯誤。當我們在編程時沒有檢查下標,並且引用了越出數組或其他類似數據結構邊界的元素時,就會導致這類錯誤。

     與使用標準 vector 類型的程序相比,依賴於內置數組的程序更容易出錯而且難於調試。

4、4.2指針的引入

      vector的遍歷可使用下標、迭代器,數組的遍歷使用下標、指針。

      指針是指向某種類型對象的複合數據類型,是用於數組的迭代器:指向數組中的一個元素。

      解引用操作符  * dereference operator     自增操作符  ++ increment operator

      指針用於指向對象。類似於迭代器,指針提供對其所指對象的間接訪問。指針用於指向單個對象,而迭代器只能用於訪問容器內的元素。

      指針保存的爲另一個對象的地址,只能初始化或賦值爲同類型的變量地址或另一指針。void *可以保存任何類型對象的地址。

       指針聲明語句時,請從右向左閱讀。

       除了使用數值0或在編譯時值爲 0 的 const 量外,還可以使用 C++ 語言從 C 語言中繼承下來的預處理器變量 NULL,該變量在 cstdlib 頭文件中定義,其值爲 0。如果在代碼中使用了這個預處理器變量,則編譯時會自動被數值 0 替換。

       給指針賦值:對左操作數進行解引用,修改的是指針所指對象的值。

       通過指針進行賦值:沒有使用解引用操作,修改的是指針本身的值。

       引用必須初始化,始終指向同一個特定對象。

       指針本身也可用指針指向的內存對象。指針佔用內存空間存放其值,因此指針的存儲地址可存放在指針中。

       **操作符指派一個指針指向另一指針。

        兩個指針的減法操作結果是標準庫類型ptrdiff_t的數據。ptrdiff_t類似於size_t類型,機器相關的類型,在cstddef頭文件中定義。size_t 是 unsigned類型,而 ptrdiff_t 是 signed類型。

         lsat = *(ia + 4) 指的是ia[0]後的第四個元素

        計算數組的超出末端指針

        for循環的性質:只要定義的多個變量具有相同的類型,就可以在for循環的初始化與劇中定義他們。

         for (int *pbegin = int_arr, *pend = int_arr + arr_size; pbegin != pendl; ++ pbegin)

         類似於其他內置類型,數組也沒有成員函數。因而,數組不提供begin和end操作。

const size_t arr_sz = 5;
int int_arr[arr_sz] = { 0, 1, 2, 3, 4 };
// pbegin points to first element, pend points just after the last
for (int *pbegin = int_arr, *pend = int_arr + arr_sz;
            pbegin != pend; ++pbegin)
     cout << *pbegin << ' '; // print the current element



 // equivalent loop using iterators to reset all the elements in ivec to 0
for (vector<int>::iterator iter = ivec.begin();
            iter != ivec.end(); ++iter)
    *iter = 0; // set element to which iter refers to 0

           內置數組類型具有標準庫容器的性質,與數組聯合使用的指標本身是迭代器。

           

              

         如果指針所指的對象是const類型,那麼指針也必須是const類型。const int  *noddle,約定的是prt而不是noddle。

         const類型的變量,必須要求對應的指針也是const類型。指向const的指針指向的對象可以不是const類型。

         void *指針也同樣要求const void *纔可以保存const變量。

int errNumb = 0;
int *const curErr = &errNumb; // curErr is a constant pointer  const指針的表達方式
curErr 是指向 int 型對象的 const 指針
const double *const pi_ptr = &pi;
 
指針和typedef
typedef string *pstring;
const pstring cstr;
cstr的類型是const pstring類型,更進一步的是指向string類型對象的const指針。
等價於string *const cstr;

const int  ic = 1; 定義了一個int型const對象ic,並用int型對象對其進行初始化
const int *p = &ic; 定義指向int型const對象的指針p,並用ic的地址對其進行初始化
int *const p = &ic; 定義int型對象的const對象,但是初始化的是const int型對象ic的地址
const int *const p = &ic; 定義指向int型const對象的const指針p,並用ic的地址對其進行初始化。

5、4.3 C-style 的字符串    

      C風格字符串是以空字符null結束的字符數組

      字符串字面值的類型就是const char類型的數組。

      C++語言通過 const char* 類型的指針來操作C風格字符串,碰到null終止運行。使用指針的算術操作來遍歷C風格字符串:     

const  char *cp = “some value”;
while  (*cp){
       ++cp;
        }

        操縱C風格字符串的標準庫函數(必須要有null結束),必須包含相應的C頭文件:#include<cstring>

        strlen(s)返回s長度,不包括字符串結束符null

        strcmp(s1,s2)比較是否相同,大於正數,小於負數

        strcat(s1,s2)將字符串s2連接到s1後,返回s1

        strcpy(s1,s2)將s2賦值給s1,並返回s1

        strncat(s1,s2,n)將s2的前n個字符連接到s1後面,並返回s1

        strncpy(s1,s2,n)將s2的前n個字符賦值給s1,並返回s1

6、4.3.1動態數組

        每一個程序在執行時都佔用一塊可用的內存空間,用於存放動態分配的對象,內存空間稱爲程序的自由存儲區或者堆。

        int *pia = new int[10]   ();    new和delete語句進行內存空間的劃定,類型+數組維數。

        const int *pia = new const int[100];

         允許動態分配空數組:

         size_t   n = get_size();

          int  *p = new int[n];

          for(int *q = p; q != p +n; ++q)

         釋放空間   delete  [ ]  pia;

#include <iostream>
#include <vector>
using namespace std;

int main()
{
    vector<int> ivec;
    int numbers;
 
    //讀入元素數據並建立vector
    cout << "Enter nubmers:" << endl;
    while(cin>> numbers)
        ivec.push_back(numbers);
    
    //創建一個與vector相同的數組
    size_t n = getsize(ivec);
    int *p = new int[n];
    int *tp = p;
    for(vector<int>::iterator iter = ivec.begin(); iter != ivec.end(); ++iter,++tp)
       *tp = *iter;
    deleter [] p;

    return 0;
}

          標準庫string與C風格的轉換:char *str = st2.c_str();  

          c_str函數返回C風格字符串,即返回指向字符數組首地址的指針,以null結尾。

          int ia[3][4] = {

                (0,1,2,3),

                (4,5,6,7),

                (8.9.10.11)    };

           多維數組的指針:typedef

  typedef int int_array[4];
  int_array *p = ia;
  for (int_array *p = ia; p != ia + 3; ++p)
      for (int *q = *p; q != *p + 4; ++q)
            cout << *q << endl;

標準輸入設備讀入字符串,並存放到字符數組。處理可變長的輸入

#include<iostream>
#include<string>
#include<cstring>   //c++中的c字符串

int main()
{
   string s1;
   const size_t n = 10;
   char s2[n+1];
   
   cout << "Enter a string(<=" << n << "characters):" << endl;
   cin >> s1;
   //比較len與n的關係,進而判斷

   size_t len = strlen(s1.c_str());
   if(len > n){
      len = n;
      cout << "String is longer than" << n << "characters and is stored only"
           << n << "characters!" << endl;
    }
   //複製元素並實現添加
   strcpy(s2, s1, len);
   s2[len+1] = "\0";   末尾添加空字符

   return 0;
}

用int型數組初始化vector對象:vector 從int數組中選擇

把int型vector複製給int型數組:  int *p = new int[ivec.size()]      delete  [ ]  p;

4.34例題:

#include<iostream>
#include<string>
#include<vector>
using namespace std;

int main()
{
   //讀入string類型的數據,並存到vector中
   string st1;
   vector<string>  ivec; 
   cout << "please input a string:" << endl;
   while(cin >> st1)
       ivec.push_back(st1);

   //複製到字符指針數組,爲元素創建數組
   char **p = new char*[ivec.size()];     //創建的“字符指針數組”需要加兩個※
 
   //爲每一個vector元素創建一個字符數組
   size_t n = 0;
   for(vector<string>::iterator iter = ivec.begin(); iter != ivec.end(); ++iter,++n){
       char *pat = new char[(*iter).size()+1];
       //複製vector元素的數據到字符數組
       strcpy(pat, (*iter).c_str());
       //將指向該字符數組的指針插入到字符指針數組
       p[n] = pat;
    }
    //釋放各個字符數組
    for(ix = 0; ix != ivec.size();++ix)
         delete [] p[ix];
    //釋放字符指針數組
         delete [] p;
    return 0;   
}

typedef簡化指向多維數組的指針 

typedef int int_array[4];   
int_array *p = ia;
for(int_array *p = ia; p != ia+3; ++p)
   for(int *q = *p; q !=*p+4;++q)
       cout<< *q <<endl;

int (*p)[4]是指向4個元素的數組的指針
int *p[4]是指向int型的數組指針

vector爲更靈活更容易管理的數組

string是C風格字符串的改進類型,而C風格字符串是以空字符結束的字符數組。指針和迭代器都能訪問所指向的對象。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章