欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
從*p++說(shuō)指針,數組,結構和函數

http://blog.csdn.net/unix21/article/details/16116737

2013

說(shuō)明文中*p++和*s++都是一個(gè)東西,不做字面上的統一了。

因為右結合性,*p++ 其實(shí)就是 *(p++) 


1.strlen的實(shí)現

  1. #include <stdio.h>  
  2. main(){  
  3.     char str[]= "Abcde";  
  4.     printf("\n string = %s length = %d \n",str,str_length(str));  
  5. }  
  6.   
  7. int str_length (const char *s){  
  8.     int length = 0;  
  9.     while (*s++){  
  10.         length++;  
  11.     }  
  12.     return (length);  
  13. }  
其實(shí)*s++的過(guò)程




遞增到最后一位就是\0,也就是“”.


注意:*s已經(jīng)指向后面的內容了,就是亂碼了



2.數組和指針這2種方式表示字符串的差異
  1. #include <stdio.h>  
  2. main( )  
  3. {  
  4.     char  str[]= "Abcde";  
  5.     char*  ptr = "12345";  
  6.     *ptr++;  
  7.     printf ("\n string = %s length = %d \n",ptr,str_length (ptr));  
  8.     printf ("\n string = %s length = %d \n",str,str_length (str));  
  9. }  
  10.   
  11. int str_length (const char  *s)  
  12. {  
  13.     int length = 0;  
  14.     while (*s++)  
  15.     {  
  16.         length++ ;  
  17.     }  
  18.     return (length) ;  
  19. }  
輸出:


2.1 數組不能直接當指針用,數組名不能指針運算
也就是說(shuō)數組名代表數組的首元素,它是一個(gè)指針常量,它的值在程序運行期間是固定不變的,  *str++是不可以的;
ptr是指針變量當然可以實(shí)現ptr++的運算但是指針自然可以指針運算。


直接數組名++就報錯了:


2.2 數組名不能直接賦值,但是指針可以

給數組名賦值就報錯了:


第1次指針地址是:0x010f5860


第2次指針地址是:0x010f5861


第3次指針地址是:0x010f5868


第4次指針地址還是:0x010f5868


下面是《明解C語(yǔ)言》書(shū)的截圖:


3.  int下*s++,(*s)++,++*s,++(*s)的差異
首先 如果*s是指針,那么*s++就不是將*s的值加1,而是將*s指向的地址加同一個(gè)單位大小。所以為了避免類(lèi)似問(wèn)題,需要的時(shí)候要加括號。

--出自《C語(yǔ)言入門(mén)經(jīng)典 第4版》

  1. #include <stdio.h>  
  2. void add(int *s)  
  3. {  
  4.     *s++;  
  5. }  
  6.   
  7. int str_length (char  *s)  
  8. {  
  9.     int length = 0;  
  10.     while (*s++)  
  11.     {  
  12.         length++ ;  
  13.     }  
  14.     return (length) ;  
  15. }  
  16.   
  17. main( )  
  18. {  
  19.     int a=1;  
  20.     int *b=&a;  
  21.     char  str[]= "Abcde";  
  22.     char*  ptr = "12345";  
  23.     *ptr++;  
  24.     ptr="def";  
  25.     add(b);  
  26.     printf ("\n string = %s length = %d \n",ptr,str_length (ptr));  
  27.     printf ("\n string = %s length = %d \n",str,str_length (str));  
  28. }  


第1次*s++之前的地址是:0x002afc98


第2次*s++之前的地址是:0x002afc9c
fc9c-fc98=4  就是一個(gè)int的大小
*s++只是對s的地址遞增然后解引用,得到-858993460,并沒(méi)有改變*s的值!


跳出函數a沒(méi)有變化


所以要想得到Int型值的遞增可以這樣寫(xiě)即可:
  1. void add(int *s)  
  2. {  
  3.     (*s)++;  
  4. }  

由于char*大小正好是1個(gè)字節,所以char*的++正好指向下一個(gè)字符!
所以在字符串的操作中正好可以用*s++,如果使用了括號,(*s)++這樣的話(huà)反而會(huì )引起內存錯誤。

4.字符串復制
  1. #include <stdio.h>  
  2.   
  3. void xstrcpy ( char  *t, char  *s ){  
  4.     while ( *s != '\0' )  
  5.     {  
  6.         *t = *s ;  
  7.         s++ ;  
  8.         t++ ;  
  9.     }  
  10.     *t = '\0' ;  
  11. }  
  12.   
  13. void strcpy(char *s,char *t){  
  14.     //while((*s++=*t++)!='\0')  
  15.     //表達式通'\0'的比較是多余的,因為只需要判斷表達式的值是否為0即可。  
  16.     while(*s++=*t++)  
  17.         ;  
  18. }  
  19.   
  20. //標準庫實(shí)現  
  21. char * strcpy2(char *s,char *t){  
  22. char *r=s;  
  23.     while(*s++=*t++)  
  24.         ;  
  25.     return r;  
  26. }  
  27.   
  28. void main()  
  29. {  
  30.     char  source[] = "Abcde" ;  
  31.     char  target[20] ;  
  32.   
  33.     strcpy ( target, source ) ;  
  34.     printf ( "\nsource string = %s", source ) ;  
  35.     printf ( "\ntarget string = %s", target ) ;  
  36. }  
  37. /* 
  38. 想經(jīng)過(guò)函數調用改變某個(gè)變量的值,就要傳入變量的地址。 
  39.  如果變量是基本類(lèi)型,要傳入對應的指針類(lèi)型。 
  40.  如果變量是指針,要傳入指針的指針。 
  41.  */  


--出自《C語(yǔ)言程序設計語(yǔ)言 第2版》



5.說(shuō)清楚函數傳遞參數


一開(kāi)始我們會(huì )想既然已經(jīng)在函數中*s++了,而且也確實(shí)改變了指針的位置,但是為什么一回到調用函數中,*s就又復原了?
不是說(shuō)傳指針是按引用傳遞的么?

其實(shí),誤區也正在于此,函數還是傳值的,傳遞的都是原值的拷貝,如果傳遞指針,在調用函數中使用*解引用,可以改變指針指向的值,但是不能改變指針的內容,因為函數調用只是傳遞了原始指針指向值地址的拷貝,就是說(shuō)原始地址拷貝了2份,所以在函數中改變是改變了地址,但是沒(méi)有意義。


int a = 0x55aa;

change_value(&a, 0xaa55);

這樣a的值改變了,真正的情況是參數傳遞后,編譯器做了一個(gè)參數拷貝過(guò)程,比如聲明一個(gè)整型指針pCopy = &a;

這樣,pCopy只是傳進(jìn)來(lái)參數&a的一份拷貝,但是他們都指向了a的地址,因此用這種方法可以改變a 的值。


那么現在有個(gè)問(wèn)題,通過(guò)傳遞一個(gè)指針,可以改變該指針所指向地址的內容,那么如何改變指針本身呢?
該怎么做才能改變ptr呢?

既然ptr也是一個(gè)變量,我要在函數內部改變它,那么就傳遞一個(gè)指向ptr的指針!也就是二級指針!



6.函數返回指針

絕不返回函數中本地變量的地址。


函數返回指針可以用如下方法:

1.可以用malloc分配內存,并返回這個(gè)內存的地址

2.返回指針參數


注意函數中可以聲明一個(gè)新的結構struct,然后返回結構,但是不可以返回臨時(shí)指針。



7.數組和指針的差異
數組不是指針,作為參數傳遞的數組會(huì )退化為指針。





為什么C語(yǔ)言把數組形參當做指針?



再來(lái)看看《你必須知道的495個(gè)C語(yǔ)言問(wèn)題》



8.數組不能被賦值
數組不能賦值,可以指定數組下標賦值,可以在函數中可以給數組賦值,因為這個(gè)時(shí)候數組退化為指針。




9.數組的大小




10.指針和結構

結構體指針4個(gè)字節,結構體大小要看數據對齊。
分配12個(gè)字節,結構吃掉8個(gè),當 (結構地址+1)所以只能第一個(gè)元素可以分配到初始化的0,第二個(gè)元素就分到垃圾地址了

  1. struct tt{  
  2.     int size;  
  3.     int slabs;  
  4. };  
  5. void main()  
  6. {  
  7.     void *s=malloc(12);  
  8.     struct tt *t1;  
  9.     memset(s,0,12);  
  10.     t1=(struct tt*)s;  
  11.     t1->size=1;  
  12.     t1->slabs=2;  
  13. }  

指針不對齊8a88  和8a90差2   8a90和8a98差8    結構有2個(gè)Int  所以結構大小是8

結構和指針的關(guān)系
對同一個(gè)地址可以轉換為任意結構體,雖然數據結構亂了,但是畢竟也是有數據。
所以使用法則也就是使用前先尋址,再強制轉換


11.變量作用域

局部變量的作用域一般認為是在函數體內。但是根據C99標準,該說(shuō)法有了變化。在新的標準中,允許即時(shí)定義局部變量,示例如下:

for( int i = 0; i < MAXSIZE; i++ )

{

….

}

例子中的局部變量i的作用域即在for循環(huán)的花括號中,當for循環(huán)結束的時(shí)候,局部變量i的生存周期同時(shí)結束。也就是說(shuō),在下一個(gè)for循環(huán)中,你仍然可以再次重新定義并使用名為i的局部變量。該語(yǔ)法只能在C99之后的新的C編譯器中使用, 例如VC2005、VC2008、gcc4.2及以上版本。但是,該語(yǔ)法帶來(lái)了編程風(fēng)格的變化,而且變量隱含在了執行程序中,無(wú)論是代碼的閱讀和維護都有較大的困難,因此工程項目中不建議使用該語(yǔ)法。


for循環(huán)中定義的pit 在離開(kāi)循環(huán)以后就不存在了。


12.傳遞結構和數組給函數的差異

為什么傳遞給函數的結構沒(méi)有像數組一樣退化為指針,因為數組可以用指針去偏移量,但是結構無(wú)法做到這一點(diǎn),或者說(shuō)非常困難。

其實(shí)函數參數默認是通過(guò)r0,r1,r2,r3四個(gè)寄存器傳遞的,多余的參數是通過(guò)將參數壓入棧中傳遞的。同理對于一個(gè)結構體如果其大小少于32字節(4個(gè)寄存器),按照正常的方式通過(guò)r0到r3傳遞,多于32字節則是將多余的部分在堆棧上建立個(gè)備份進(jìn)行傳遞。

    所以對于在A(yíng)DS編譯器下對于函數參數是結構體的傳遞,還是傳入指針比較好。既高效(省去建立備份的時(shí)間),又節省??臻g。


13.指針大小

32位是4個(gè)字節,32=4*8     

64位是8個(gè)字節,64=8*8     

在64位的linux下:

而visual studio里默認是win32平臺,指針是4個(gè)字節大?。?/p>


需要修改為x64平臺

這時(shí)候顯示指針是8個(gè)字節:



14.指向數組的指針
slabclass_t *p = &slabclass[id];


 
本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
函數指針&指針函數
一道試題引發(fā)的血案
C語(yǔ)言經(jīng)典筆試題(一)
啟明星辰2011校園招C筆試題(一)
Delphi基礎教程圖文版之指針
C語(yǔ)言中字符串數組與字符指針數組有什么區別?怎么用?
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久