C指针数组

在本节中,我们通过使用整数指针的数组来说明使用指针数组的关键点。指针数组的例子也出现在下面几处:

本节的目的是说明这种方法的本质,来为接下来的几个例子打好基础。下面的代码片段声明一个整数指针的数组,为每个元素分配内存,然后把内存的内容初始化为元素的索引值:

int* arr[5];
for(int i=0; i<5; i++) {
    arr[i] = (int*)malloc(sizeof(int));
    *arr[i] = i;
}

如果把数组打印出来,得到的是数字0到4。我们用arr[i]引用指针,用*arr[i]把值赋给指针引用的位置。别被数组表示法搞糊涂了,因为arr声明为指针数组,arr[i]返回的是一个地址,当我们用*arr[i]解引指针时,得到是这个地址的内容。

我们也可以在循环体中使用下面这种等价的指针表示法:

*(arr+i) = (int*)malloc(sizeof(int));
**(arr+i) = i;

这种表示法更难理解,但是理解以后能加强你的C技能。在第二个语句中我们用了两层间接引用,掌握这种表示法将让你和初级C程序员有本质区别。

子表达式(arr+i)表示数组的第i个元素的地址,我们需要修改这个地址中的内容,所以用了子表达式*(arr+i)。在第一条语句中我们将已分配的内存赋给这个位置。对(arr+i)子表达式做两次解引(如第二条语句所示),会返回所分配内存的位置,然后我们把i赋给它。图4-9说明了内存的分配情况。

图4-9:指针数组

比如说,arr[1]位于地址104,表达式(arr+1)为我们返回104,用*(arr+1)则让我们得到其内容,在本例中,就是指针504。再用**(arr+1)解引它就得到了504的内容,就是1。

表4-3中列出了一些示例表达式。从左到右读指针表达式且不要忽略括号,这样会更容易理解其工作方式。

表4-3:指针数组表达式

表达式
*arr[0] 0
**arr 0
**(arr+1) 1
arr[0][0] 0
arr[3][0] 3

前三个表达式和前面解释的差不多,最后两个则有所不同。用指针的指针表示法能让我们知道正在处理的是指针数组,实际上我们的示例中也用到了。如果再看一下图4-9,假设arr的每个元素指向一个长度为1的数组,那么最后两个表达式就能说通了,我们得到的是一个有5个元素的指针数组,这些指针指向一系列有1个元素的数组。

表达式arr[3][0]引用arr的第4个元素,然后是这个元素所指向的数组的第1个元素。表达式arr[3][1]有错误,因为第4个元素所指向的数组只有一个元素。

这个例子提醒我们可以创建不规则数组,这确实行得通,不规则数组和指针讲的就是这个主题。

赞(1)

评论 抢沙发

评论前必须登录!

 

C指针