C語言中的sizeof中的數組和指針


1.引子

    今日在看動態規划的0-1背包問題,看完后還是打算自己寫着試試,畢竟實踐才能出真知嘛.動態規划的結果是個二維數組dp,我copy書上的例子進行初始 memset(dp,0,sizeof(dp)),考慮到程序的健壯性,對於數組我都是用的動態申請,自然二維數組也不例外[動態二維數組的建立可參見本blog的延伸].

    程序寫完后,但是卻不能運行,開始單步調試,當進行到dp的賦值時老是報指針的錯誤!!!開始我以為是指針越界什么的,仔細才發現dp的數組維數確實要多申請一個用來存放初始情況的值(全是0).但還是不行.只要乖乖的用兩個for循環來賦值,這下程序確實可以出結果了.這說明剛才確實是初始化的時候出了問題.這才把問題瞄准了memset(dp,0,sizeof(dp)).

printf("%d",sizoef(dp)); 我的dp是5行6列,結果是4?

2.思考

    百度下memset,尤其是對整形數組進行初始化的部分.memset是以字節為單位進行初始化的.然后自己就寫了個一維數組的demo試試:

    

1  int b[5];
2  int *c;
3  c = malloc(sizeof(int)*5);
4  memset(b,0,sizeof(b)); // 這個是可以成功的 
5  memset(c,0,sizeof(c)); // 也可以執行
6  printf("%d",b[2]);  //結果是0,b[0~3] = 0;
7  printf("%d",c[2]);  //結果卻不是0!!!;
8  printf("%d %d",sizeof(b),sizeof(c));

 

       b[2] 與 c[2]的值不一樣,兩者的初始化的差別就在sizeof(b)與sizeof(c)上,這兩個的結果是20,4!!!

       memset是以字節為單位進行初始化,第4行對b的20個字節全部初始化了,第5行只對c的前4個字節初始化了,c指向的還是20個字節的內存,所以c[0] = 0;但是c[1~3]就不是了.

       這兩個的不同差別在哪呢?參閱sizeof

       首先這是個操作符而不是一個函數.計算數據類型的長度符的.上述中c和b都是存放5個整數,有什么不同嗎?

       int b[]是一個數組,sizeof()值是其數據類型的sizeof值*其數組的長度;

   int *c是一個指針變量,sizeof中說明了一個指針變量的sizeof值必定是4(32bit),與其指向的數據類型無關;

3.解決

       然后在看動態規划的例子中dp是聲明的二維數組dp[][],而我是的是int **dp;是一個指向指針的指針,所以是4;

       參考對一維數組初始化的例子,可以這樣:

       

 1 // C++ -version
 2 int **array;
 3 array=new int *[10];
 4 for(int i=0;i<10;i++)
 5 
 6 {
 7          array[i]=new int [5];
 8 
 9        memset(array[i],0,5*sizeof(int));
10 
11 }

      c語言的把new 換成malloc即可!  

4.延伸

    1. 動態的二維數組

     

1 int r,c;
2 int **a;  //創建二維指針來指向數組
3 scanf("%d%d",&r,&c);
4 a  = (int **) malloc(sizeof(int *) * r);//注意申請的指針格式
5 for (j=0;j<r;j++){
6 a[j] = (int *) malloc(sizeof(int) * c);
7 ……
8 ……
9 }

     2. memset對整形數組初始化的錯誤是初始化為1,memset對整形只能初始化為0,這個情況memset中有講;

         更多閱讀課參考如下:

         http://blog.csdn.net/qtyl1988/article/details/8033181

 PS: 此blog是過了一夜寫的,個人也忘了當初怎么就把錯誤的原因一步步的關注到sizeof的,我記得我好想開始還不是關注的此處.反正是又學到了!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM