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的,我记得我好想开始还不是关注的此处.反正是又学到了!

 

posted @ 2014-08-10 09:53  Programmer-cjr  阅读(3179)  评论(0编辑  收藏  举报