1、數組是自動分配空間,指標要手工分配空間(int *p = new int;)
2、在Unix上,程式出現段錯誤的時候,系統會產生core 檔案,會把出現錯誤的那一刻的程式鏡像儲存在此檔案中
3、結構的成員變數出現數組:
struct Account{ long id ; //char name[ 50 ] ; //char password[ 10 ] ; char * pname ; char * ppwd ; double balance ; };
數組長度100-200位元組,最好用數組做,這樣方便
數組很大的時候,可以考慮用指標,賦值的時候要注意:
a.pname = new char[50];
strcpy(a.pname , "huxinzhe");
在結構聲明時,不能給成員變數賦值
結構聲明只是聲明了一種資料類型,還沒有為這個結構申請空間,賦值的資料沒有空間儲存
4、危險指標的用法
使用NULL指標的內容 ---隱蔽性不高,容易發現
使用沒有初始化的指標 --- 會導致無意當中修改其它變數,破壞性很大,避免的辦法 int *p = NULL;
使用已經被delete的指標內容 --- 修改其它變數 避免的辦法 delete p ; p=NULL;
返回一個局部變數的地址
由函數申請空間,由調用者釋放
View Code
#include <iostream> using namespace std; char * readLine(){ char * line = new char[ 100 ] ; //在函數中申請了空間,但是沒有地方釋放 strcpy( line , "hello world" ) ; cout<<"line = " << line << endl; return line ; //返回變數的指標,若是局部變數,在函數返回的時候,就消失了,若在堆中申請空間,沒有釋放空間的機會 } int main(){ char * p = readLine(); cout<<"return from readLine "<<endl; cout<<"p = " << p << endl; delete p; //釋放別人申請的空間,不安全 return 0 ; }
解決的辦法 : 在函數外部申請一個指標並初始化,作為參數傳給函數,這樣可以儲存資料並返回
在參數中傳數組的起始地址,和數組長度
只要是參數傳指標,指標在傳給函數之前要進行初始化
5、編譯的時候不想看到警告資訊 g++ -w
6、函數指標的聲明:
函數的名字就是這個函數的首地址
函數指標之間的賦值,也要同類型的
函數指標是不需要釋放的。
函數指標,設計通用演算法
7、多層指標
int i = 10; int * p = &i; int ** pp =&p; int**(*ppp) = & pp; *p = i ; *pp = p; **pp = i;
多層指標的使用 :
int ia[2][3] = {{11,12,13}, {21,22,23}}; //聲明並定義一個二維數組 cout << ia[0] << endl; //列印的是ia的第一個數組的首地址 int * p = ia[0]; //儲存ia第一個數組的首地址 cout << a[0][2] <<endl; cout << p[2] <<endl; //與上面一行具有相同的效果 。 ia[0]的類型就是int*類型的,指向ia的第一個數組 ia也是個指標類型,指向那個二維數組 ,是 int**
二維數組是一個二級指標
二維數組的每個元素是一級指標
int (*pp)[3] = ia; //行指標,指向二維數組的一行,[]中的數字表示每一行的元素個數 cout << pp[1][1] <<endl; //通過二級指標去數組元素 pp[1][1] <=> *( *(pp+1) +1 )
行指標可以描述指向數組的元素個數,以行為單位,加1就是指標指到下一行
列印數組在記憶體中地址
int (*p1)[3] --> p1的類型是int[3] p1+1,走3個int,一個數組的長度 int ** p2 --> p2的類型是int* p2+1,走1個int
8、
char* names[100]; 聲明一個數組,每個元素類型是char* chat* names[3] = {"liucy","huxz","tangliang"}; //這樣的聲明更清晰的說明是char的二維數組 for(int i = 0 ; i < 3 ; i++){ cout << names[i] <<endl; //列印每個元素 }
9、void*
任何類型的變數的地址都可以把地址存進來
通用指標的儲存,不能做任何運算,是純粹的儲存地址而用
10、const與指標
const int *p 常量指標 不能通過指標改變變數的值 const離int近,值不能改
int* const p 指標常量 指標不能改,指向的對象是固定的,但可以通過指標改變變數的值
11、指標的要求
指標的聲明和基本運算
數組與指標的關係,結構和指標的關係,字元指標的用法
堆空間及危險用法
12、引用
引用就是一個變數的別名 int &iR= i; //給i起的別名iR
引用聲明的時候必須初始化(與一個變數保持關聯關係),一旦賦值,就不能把別名再給別的變數了
int iL = 100;
iR = iL; // 相當於把i的值改變了,iR還是i的別名
13、引用的使用
以引用的形式傳參數 fn(int &a)
在函數內部的操作就是對此實參進行操作
一般情況下 (1)在真的想改變實參的值的時候
(2)在實參的大小比較大的時候,傳引用,這樣系統不產生臨時變數,減小耗費記憶體
的時候傳引用。
fn(const int &a) 這樣傳引用,不會建立臨時變數,也不會改變實參的值
14、周末項目
(1)完善項目 把密碼用char數組儲存
(2)寫一個函數,對所有類型的數組進行排序
提示:通過函數指標實現對struct傳參數
void* 指標,儲存所有類型指標
View Code
void sort (int perlen , int *p , int len , void (*order)(int * ,int *)){ char *p1 = (char*)p; //char是基本類型裡最小的,可以類比步長 for(int i = 0 ; i < len ; i ++{ for(int j = 0 ; i < len ; i++){ order(p+i*prolen,p+j*prolen); } } )