C语言小结--指针和数组的结合

来源:互联网 发布:农村选举知乎 编辑:程序博客网 时间:2024/05/17 19:18

1、数组和指针有什么关系

我们知道,访问一个变量的内容的实质就是访问内存,访问一个变量可以通过变量名访问,也可以通过指针来访问。如下的两种操作printf结果是一样的:

#include <stdio.h>int main(void){    int a = 10;    int b;    int *p;    b = a;    p = &a;    printf("b = %d;\n",b);    printf("*p = %d;\n",*p);    return 0;}

结合上一章提到的,int a[10] ; 中a就表示数组的首地址,那么我们定义int *p,就可以赋值为p = a;那么可以通过*p来访问数组了,这样数组和指针就建立了联系。同样的,我们可以直接把a作为一个指针来用,可以*a来访问数组元素。

#include <stdio.h>int main(void){    int a[5] = {1,2,3,4,5};    printf("*a = %d;\n",*a);    return 0;}

结果:

root@ubuntu:/mnt/hgfs/share/code/c_adcance/priner# ./a.out *a = 1;

2、从内存角度理解指针访问数组的实质

(1)数组的特点就是:数组中的各个元素地址是依次相连接的,而且数组必须是一种数据类型。
(2)数组占用地址连续的一片内存空间,只要知道其中一个数组元素的地址,就可以推算出其他数组元素的地址。这个特点特别好用指针去是实现。

3、指针和数组类型匹配的问题

(1) int *p ; int a[5]; p = a ;//类型匹配
(2) int *p; int a[5]; p = &a; //类型不匹配
(3) 虽然&a 、a 、 &a[0] 三个表示方式从数值上来看是完全相等的,但是其表示的意义不一样。a和&a[0]表示的数组元素的首地址,而&a表示的是整个数组的首地址。从类型上来看:a、&a[0]是元素的指针,是int 类型的;而&a是数组指针,是int ()[5]。

4、指针类型决定了指针如何参与运算

(1)指针参与运算时,因为指针变量本身存储的数值是表示地址的,所以运算也是地址的运算。
(2)指针参与运算的特点是,指针变量+1,并不是地址真的+1,而是+1*sizeof[指针类型];如果是int 类型,则+1实际是地址+4,如果是char 类型的指针,则+1则表示地址+1;如果是double *类型的指针
,则就表示地址+8。
(3)指针变量+1时,实际不是+1而是+sizeof[指针类型],主要原因是希望指针+1后刚好指向下一个元素(当然不希望错位了)。这样在指针操作时就非常方便。

总结一下,代码体现:

#include <stdio.h>int main(void){    int a[5] = {1,2,3,4,5};    int *p;    p = a;    printf("*p = %d. \n", *p);    printf("p = %p. \n", p);    printf("*(p+1) = %d. \n", *(p+1));    printf("((unsigned int)p+1) = %x. \n", ((unsigned int)p+1));    printf(" *(char *)((unsigned int)p+1) = %d. \n", *(char *)((unsigned int)p+1));    printf(" *(int *)((unsigned int)p+1) = %d. \n", *(int *)((unsigned int)p+1));    return 0;}

当能分析出打印结果时,表明指针和数组的初步结合就已经搞明白了。打印如下:

root@ubuntu:/mnt/hgfs/share/code/c_adcance/priner# gcc array_pointer.c root@ubuntu:/mnt/hgfs/share/code/c_adcance/priner# ./a.out *p = 1. p = 0xbf9355dc. *(p+1) = 2. ((unsigned int)p+1) = bf9355dd.  *(char *)((unsigned int)p+1) = 0.  *(int *)((unsigned int)p+1) = 33554432.