c语言 —— 指针与数组

  数组和指针的关系比较密切,这里再总结一下这个知识点。由问题引入话题:

    1. char a[] 和char *a等价吗?
    不是。
     数组定义char a[6]请求预留6个字符的位置,并用名称a表示。也即:有一个用a标识的位置,可以放入6个字符。
    而指针声明char *p :请求一个位置放置一个指针,用名称p表示。这个指针可以指向任何字符或任何连续的字符,或者哪里都不指。通过图像来说明:
    若有下面语句:
    char a[] = "hello";
    char *p = "world";

 它们在内存中的表现形式如下(当然,箭头是我们人为添加的):

 注意:数组不能被赋值。但是指针可以。在使用指针过程中一定要清楚指针本身和指针指向的内容,尤其是指针运算。指针运算总是居于所指对象的大小的。
    
2. 如何理解“指针和数组等价”?
         在C语言中知识指针算数和数组下标运算等价,指针和数组是不同的。那么,在作为函数形参的数组和指针为何可以互换呢?其实,给函数传入数组只是一种便利的做法。在这个过程中,数组会马上退化为指针,事实上,数组从来没有被传入函数。 例如:
void fun(int a[])
{...}

在编译器里都被当做指针来处理。因为在传入数组的时候,函数接受到的正是指针。
    注意这种转换仅限于函数形参的声明,在别的地方并不适用。

3.  如何动态分配数组?
     (1)动态分配一维数组:用指向malloc分配的内存的指针来高效模拟数组。
         int *dArray = (int *)malloc(10 * sizeof(int));
    
     (2)动态分配二维数组:
      方法一:分配一个指针数组,然后把每个指针初始化为动态分配的“行”。
int **arr1 = (int *)malloc(rows * sizeof(int *));
for (i = 0; i < rows; i++)
{
        arr1[i] = (int *)malloc(cols * sizeof(int));
 }

内存布局:



    方法二:让数组的内容连续。但在分配行的时候要使用一点指针运算:
        
 	int **arr2 = malloc(rows * sizeof(int *));
 	arr2[0] = malloc(rows * cols * sizeof(int));
  	for (i = 1; i<rows; i++)
        {
               arr2[i] = arr2[0] + i * cols;
        }

           内存布局:

    方法三:用一个动态分配的一维数组来模拟二维数组:
          int *arr3 = malloc(rows * cols * sizeof(int));
          但是在使用是偶必须手工计算下标,如:arr3[i * cols + j]访问第i、j个元素。
    
     方法四:使用数组指针:
          int (*arr4)[COLS] = malloc(rows * sizeof(*arr4));
          或,
          int (*arr5)[ROWS][COLS] = malloc(sizeof(*arr5));
          这种方法的语法比较可怕,并且运行时最多只能确定一维。
4. 如何释放前面动态分配的数组?
    对于arr1和arr2:
    
    for (i=0; i<rows; i++)
        free((void *)arr1[i]);
    free((void *)arr1);

    注意:释放的原则:每个malloc()都必须有一个对应的free();

5. 如何给函数传递一个二维数组?
    数组退化为指针的规则不能递归应用。数组的数组(二维数组)退化为数组的指针,而不是指针的指针。
    若想函数传递二维数组:
 int arr[ROWS][COLS];
 fun(arr);
    那么,函数的声明也必须匹配:
         
    void fun(int a[][COLS])
    {...}

    或者         
     void fun(itn (*pArr)[COLS])  /* pArr is a pointer to an array */
    { ...  }


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值