1.简述
c语言中用形如:
int * p = #
这样的方式来定义一个指针,指针p代表了num的地址。
而指针与地址是不等价的,它俩的重要区别是指针是有类型的;
这里简单的介绍一下内存地址:
8位为1字节,每8位我们给它分配一个地址,每个地址由32位二进制数组成(对32位cpu而言;32位cup所能寻找到的地址为32位),我们知道32位二进制数组成的数字共有2^32个,也就是说总共有2^32个地址,每个地址占了1个字节,所以内存空间为2^32byte = 2^32 / 1024 / 1024 / 1024 = 4G.
试想如果只告诉你内存中的一个地址,你如何知道要读取几个从这个地址往下的内存空间。所以不仅要告诉你内存地址,还要告诉你往下读取几个内存空间中的值。
上面定义的指针p指向的是int型的变量,由于int型的变量占4个字节,这样我们就知道指针p指向的变量占4个字节,于是我们就从指针p指向的地址接着往下寻找3个地址。
2.一维数组
一维数组的定义形如下列:
int a[3] = {1,2,3};
- 对于一维数组需要注意的一点是,数组名a当做参数传入函数时,传入的是地址,这时在函数中对a做的变动会改变数组a[]中的值。
比如下面的change(int [])函数,如果我们change(a),执行之后a中的值就变为了{4,2,3}。
void change(int b[]){
b[0]=4;
}
*(a+2)等价于a[2]
使用
sizeof
需注意
printf("%d",sizeof(a));
a虽然表示指针,但是此时会打印整个数组的容量,int型占4个字节,数组长度为3,所以会打印12;也就是说a指针指向数组的首地址,寻址的长度为12;
printf("%d",sizeof(&a));
&a表示一个指针。此时会打印4,因为在32位系统下,指针占用4个字节。
printf("%d",sizeof(*a));
*a为数组的第一个元素,为int型,所以会打印4;
3.二维数组
下面的代码定义了一个二维数组
int a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};
a 1 2 3 4
a+1 5 6 7 8
a+2 9 10 11 12
- 该数组为3行4列; 每一行都是一个数组,有一个行指针指向该行;
- a指向第0行地址,a+1指向第1行地址,a+2指向第2行地址。既然a+1指向第1行,对它解引用(
*(a+1)
)就获得了第1行(一个数组),*(a+1)
代表一个数组,所以*(a+1)
就为第1行的首地址。*(a+1)
等价于a[1]
。 a[1]+1
表示第一行、第一个元素的地址,对其解引用即可获得第一行、第一个元素的值。即*(a[1]+1)
等价于a[1][1]
下面通过打印一些值来进一步理解二维数组的指针:
printf("%d",sizeof(a));
会打印整个二维数组的size,为3*4*4=48
printf("%d",sizeof(a[1]));
会打印行数组的size,为4*4 = 16
printf("%d",sizeof(*(a+1)));
与上面一个相同printf("%d",sizeof(*(*(a+1) + 1)));
取出了a[1][1]
,为int型,所以打印4