天天看点

c语言 —— 指针与数组

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

    1. char a[] 和char *a等价吗?

    不是。      数组定义char a[6]请求预留6个字符的位置,并用名称a表示。也即:有一个用a标识的位置,可以放入6个字符。     而指针声明char *p :请求一个位置放置一个指针,用名称p表示。这个指针可以指向任何字符或任何连续的字符,或者哪里都不指。通过图像来说明:     若有下面语句:
char a[] = "hello";
    char *p = "world";
           
 它们在内存中的表现形式如下(当然,箭头是我们人为添加的):
c语言 —— 指针与数组
 注意:数组不能被赋值。但是指针可以。在使用指针过程中一定要清楚指针本身和指针指向的内容,尤其是指针运算。指针运算总是居于所指对象的大小的。      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));
 }
           
内存布局:
c语言 —— 指针与数组
    方法二:让数组的内容连续。但在分配行的时候要使用一点指针运算:         
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;
        }
           
           内存布局:
c语言 —— 指针与数组

    方法三:用一个动态分配的一维数组来模拟二维数组:           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 */
    { ...  }
           
c