實習整理(二)

先寫下自己在準備過程中所整理的資料,當然,這些資料不一定對於每個人都有用,只是自己碰到了而已,寫得有問題的請隨時提出,以便改正。。。
1.C++中求字符串長度的函數爲:
            string s;
            s.length();


2.C++中指針和數組的關係
    以字符數組爲例,字符數組實質上就是字符串,可以用字符串直接賦值
    char s1[6]="abcde";//char s1[]={'a','b','c','d','e'};
    char *s2=0;//不指向任何對象的指針
    s2=s1;//數組名s1代表了數組的首地址,即s2=&s1[0];
    char s3=*s2;//將字符數組的首元素賦值給s3,即s3=s1[0];
    *(s2++)和*(++s2)的區別:
    若s2當前指向s1的第三個元素,則前者爲取出第三個元素之後再指向第四個元素,後者爲指針先往後移指向第四個元素,接着取出第四個元素
    *(s2++)和*s2++的區別:
    若s2當前指向s1的第三個元素,則前者爲取出第三個元素,返回第三個元素值,之後再指向第四個元素, 後者爲取出第三個元素,讓該元素自加,返回自加的結果,指針仍指向第三個元素
    指針數組和數組指針的區別:
    前者的形式爲:數據類型 * s4[長度]=......  
    char * s4[3];//定義一個長度爲3的數組,數組的類型爲字符指針, s4[0]=s1;//將s1的首地址賦值給指針數組的第一個元素
    後者的形式爲:char * s5=s1;//指向數組的指針 或者爲:char (* s4)[3]
    void * s6;//可以指向任何數據類型的指針  s6=s1....
數組名不能進行賦值運算
此外:int a[4]={1,2,3,4}
a的類型:int *
&a的類型:int (*) [4]
int (* p1)=&a  int * p2=a;
二維數組也可以相似理解,同時指向數組的指針指的是指向整個數組元素的指針,而不是數組中單個元素的指針
注意:指針最容易發生內存泄露,即內存沒有任何指針指向,因此在編程時要注意,我覺得在使用指針時爲了避免產生混亂,最好在紙上將指針的指向情況畫出來


跳躍下:重寫 和 重載
重寫:子類覆蓋父類的方法,方法名,參數個數,類型,方法的返回類型都一樣
重載:類中有兩個或者兩個以上的方法具有相同的名稱,但參數個數或者類型不一樣


插播下:指針常量 和 常量指針
反正以前一直靠記憶,都很容易記混,現在找到一個比較好的理解方法了
const--常量  *--指針
誰在前先讀誰,誰在前就是誰不可以變
const int * a /int const * a  常量指針,指針指向的內容不能變,指針可以變 
int * const a 指針常量,指針不能變,指針指向的內容可以變,但不能通過指針來修改內容,如 *a = ... 這樣子編譯雖然能夠過,但會發生內存問題,因此也是非法的


3.C++中沒有獲取數組(字符數組除外)長度的API,字符數組可以通過strlen()來獲取長度,字符串可以通過length()獲取長度,如:
    int [] n1={1,2,3};char n2[]={'a','b','c'};string n3="def";
    int len1=sizeof(n1)/sizeof(n1[0]);//獲取int數組長度
    int len2=strlen(n2);//獲取字符數組的長度
    int len3=n3.length();//獲取字符串的長度
C++中若數組作爲函數參數,如:
int main()                                      
{
intn[]={1,2,3,1,5,6,7,8,0};
test(n);
}
voidtest(intm[])
{
intlen1=sizeof(m)/sizeof(m[0]);
for(inti=0;i<len1;i++)
{
cout<<m[i]<<endl;
}
}
則輸出結果爲1,即數組n的首元素,因爲傳遞給m的是n的首地址,因此此時m只指向第一個元素,因此長度爲1,所以要想使m完全等於n,一定要指明其作用域的範圍,這點很容易忽視,因此如果不能很好的把握,最好還是不要選擇數組作爲函數參數,Java中這點上使用就很方便
int main()                                      
{
intn[]={1,2,3,1,5,6,7,8,0};
test(n,sizeof(n)/sizeof(n[0]));
}
voidtest(intm[],int len)
{
intlen1=len;
for(inti=0;i<len1;i++)
{
cout<<m[i]<<endl;
}
}
輸出結果爲:1,2,3,1,5,6,7,8,0


4.以32爲機器爲例,各數據類型所佔的字節數

64位的話long爲8
當在求一個指針變量時要注意,指針是指地址,所以指針變量所佔的字節數就爲地址所佔的字節數,如32位機器,則地址就爲32位
此外,在使用sizeof()求所佔字節數時要注意以下幾點
4.1

sizeof()內的運算不執行,如:int i=1; sizeof(i++) cout<<i<<endl; 則i的結果仍爲1
4.2 sizeof()的結果爲無符號整數類型 unsigned int
4.3 sizeof(字符串)要將字符串末尾的'\0'算上,如sizeof("abc")的結果爲4 漢字佔兩個字節,英文字母佔一個字節
4.4 sizeof(結構體)時採用擺放元素法,注意兩條基本原則:
(一):整體空間爲結構體中sizeof最大的成員空間的整數倍,通常在擺放完所有的元素之後考慮這一點;
(二):擺放某元素時當前已佔用的內存空間應爲該元素類型大小的整數倍
PS:若結構體中又有結構體,則整體空間爲父結構體及子結構體中sizeof最大的成員空間的整數倍,同時擺放子結構體時當前已佔用的內存空間應爲子結構體中最大元素大小的整數倍;若結構體中有數組,則數組不應被當做整體來對待
union聯合體所佔空間大小爲sizeof最大的成員所佔的空間,且也要遵循struct的第一條原則;enum枚舉體的sizeof爲4;空結構體的sizeof爲1
4.5 void foo() {} sizeof(foo):錯誤,函數名稱不能進行sizeof操作 sizeof(foo()):錯誤,因爲foo函數返回類型爲void 若爲int foo() {},則sizeof(foo())的結果爲4
4.6 重定義即typedef不佔字節,即sizeof操作的結果爲0
4.7 關於計算類的sizeof和計算struct的sizeof類似,注意類中有虛函數的話,就會有個虛函數表指針(+4),虛繼承基類則會有個虛繼承表指針(+4),詳情可以查看如下博客:
http://blog.csdn.net/valerie_7/article/details/6757664
1.不存在虛繼承:
1.1 沒有父類 and 沒有成員 and 沒有虛函數 :sizeof(類名) = 1
1.2 沒有父類 and 有若干個成員 and 沒有虛函數 :sizeof(類名) = sizeof(成員)
1.3 沒有父類 and 沒有成員 and 有虛函數 :sizeof(類名) = 4(32位)/8(64位)
1.4 沒有父類 and 有若干個成員 and 有虛函數 :sizeof(類名) = sizeof(成員) +4(32位)/8(64位)
1.5 有一個父類 and 沒有成員 and 父子都沒有虛函數 :sizeof(類名) = 1
1.6 有一個父類 and 沒有成員 and 父子至少一個有虛函數 :sizeof(類名) =4(32位)/8(64位)
1.7 有多個父類 :sizeof(類名) = 注意:單獨考慮每個父類,如果該類中父或子至少有一個有虛函數,就都應該有張虛函數表,其他的計算與上面的類似了
總結而言:sizeof(類名) = sizeof(父類成員+子類成員) + 虛函數表指針 最後的結果要是指針和父類成員或者子類成員中最大sizeof的整數倍
2.存在虛繼承:
就要考慮子類指向父類的一個指針 sizeof(類名) = sizeof(父類成員+子類成員+虛函數表指針+子類指向父類的一個指針)


未完待續。。。


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