c语言中的指针与数组
2015-07-14 23:56
453 查看
c语言中的指针与数组
标签(空格分隔): c前言
前面一节,仔仔细细的学习了语言中的指针是干嘛,它的定义、初始化赋值、取值等操纵,有了一个大致的了解。这一节,看指针是如何和数组紧紧结合在一起的。指针指向数组
前面已经用指针指向一个字符,由于,指针就是指向一个元素的首地址,所以,数组也是一样://定义一个有2个整形数字的数组。总共占用4个字节的空间。 int a[2] = {1,4}; int *p; //定义一个整型指针 //将数组的首地址(第一个元素的地址)赋值给指针p,也就是p指向数组a p = &a[0]; //将指向的首地址的空间值改成5,也就是讲数组的第一个元素改成10 *p = 10;
用图来表示内存的变化就是:
学过数组这章,我们知道。数组名a其实是一个常量,它表示它的第一个元素的地址。也就是说
a == &a[0]。所以,上面的第9行也可以改成:
p = a;
那如果,我想改变
a[1]的值咋办呢?那么必须要指针指到
a[1]这个位置。那么这个时候,我们可以就要用到指针+1操作来指针移动了。
一开始,p指向
a[0], 那么
p+1就会指向
a[1]了。
需要注意的是,这个+1 并不是内存上的一个字节上的地址加1,而是根据数组内的元素的类型,往下移动一个长度。
所以,上面的+1,实际上是移动了2个字节的位置。那,如果你定义char类型的字符串数组,+1 就会移动一个字节的位置,下面是常用的类型数组内,+1移动的字节数:
所以,你这么理解:
+1就表示指地址移动数组下一个元素的位置上了。就可以了。
回到这个例子上,我想取到a[1]的值,就可以这样操作了:
int value = *(p+1); //指针加1,再取出它指向的值。
上面的操作只是取出了指针p的值得到地址,然后根据地址+1,跳到下一个元素的地址上,取到它的值。p始终还是指向&a[0]没变的。
用图表示是:
其实,我们也可以直接移动指针,也可以达到同样的效果, 先移动指针,p的值就变成了ffc5,再根据ffc5取出它的值。
p++; // p = p+1; int value = *p;
用图表示就是:
指针与数组的关系
数组与指针有着千丝万缕的关系,前面简单的说了一些。就拿最简单的一个来说。一个数组的名字其实是个常量,它表示的就是这个数组第一个元素的地址。这一点就说明了数组与指针的关系。
我们继续深挖。
用数组名作为函数实参时,是把实参数组的首地址传递给形参数组,两个数组共同占用同一段内存空间,这样形参数组中的元素值发生变化就会使实参数组的元素值也同时变化:
//形参是数组 void change(int b[]) { b[0] = 10; } int main() { // 定义一个int类型的数组 int a[4] = {1, 2, 3, 4}; // 将数组名a传入change函数中 change(a); // 实际上传递的就是地址。 // 查看a[0] printf("a[0]=%d", a[0]); //输出10。 return 0; }
change函数的形参是
数组类型的,在第11行调用change函数时,将数组名a,也就是数组的地址传给了数组b。因此数组a和b占用着同一块内存空间。
这种地址的传递也可以用指针来实现。函数的实参和形参都可以分别使用数组或指针。这样就有4种情况:
实参 | 形参 |
---|---|
数组名 | 数组 |
数组名 | 指针 |
指针 | 数组 |
指针 | 指针 |
//形参是指针 void change(int *b) { b[0] = 10; } int main() { // 定义一个int类型的数组 int a[4] = {1, 2, 3, 4}; // 将数组名a传入change函数中 change(a); // 实际上传递的就是地址。 // 查看a[0] printf("a[0]=%d", a[0]); //输出10。 return 0; }
//形参是数组 void change(int b[]) { b[0] = 10; } int main() { // 定义一个int类型的数组 int a[4] = {1, 2, 3, 4}; int *p = a //或者 int *p = &a[0]; //将指针p传入change函数中 change(p); // 查看a[0] printf("a[0]=%d", a[0]); //输出10。 return 0; }
//形参是指针 void change(int *b) { b[0] = 10; } int main() { // 定义一个int类型的数组 int a[4] = {1, 2, 3, 4}; int *p = a //或者 int *p = &a[0]; //将指针p传入change函数中 change(p); // 查看a[0] printf("a[0]=%d", a[0]); //输出10。 return 0; }
以上四种都是可以改变数组的值的,说明,他们公用的是同一个地址。在很多情况下,指针和数组是可以相互切换使用的。但是,并不能说指针就等于数组。
总结下
p是一个指针,a 是一个数组,p 指向 a 。那么:
1. p+1表示指向数组该元素的下一个元素。p = &a[0],则p+1表示a[1]的地址。
2. p+i和a+i都可以表示元素a[i]的地址,它们都指向数组的第i个元素。a代表数组首地址,a+i也是地址,它的计算方法与p+i相同
*(p+i)和*(a+i)都表示数组元素a[i]。
3. 虽然p+i和a+i都指向数组的第i个元素,但二者使用时还是有区别的。因为作为指针变量的p可以改变自身值,如p++,使p的值自增。而数组名a是一个代表数组首地址的常量,它的值是不能改变的,即a++是不合法的。
相关文章推荐
- stl变易算法(二)
- 【C++】深度探索C++对象模型读书笔记--构造函数语义学(The Semantics of constructors)(四)
- iOS面试之C语言
- C++语言编程基础1
- 探测法的哈希表的C++实现(最新修改)
- 【转载】用纯粹的C++编写COM组件
- 二叉树重建示意图
- c++primer之vector
- C语言运算符及语句篇
- C语言定义数组指针的三种方法
- 【C++】深度探索C++对象模型读书笔记--构造函数语义学(The Semantics of constructors)(三)
- c语言如何在控制台输出%
- C语言中的运算符1
- 菜鸟学习c++—实现简单的冒泡排序和插入排序算法
- 面题2 C++实现单例模式
- C语言中的运算符
- C/C++运算符及其优先级
- 轻量级数据sqlite的C++调用示例
- c语言程序设计(第1讲)关键字
- 来北京的日子(3)--排序算法