指针是一个重要的东西,没有了指针,该怎么活啊。
通过对数组的了解,我们知道要获取数据,我只需要它的索引值就可以了,这个就启发了那些人(我猜的),搞了指针出来。通过指针来得到数据。
首先先说说内存,内存可以认为是一个连续的细胞组合。计算机能管理的最小单位是 1 byte。 这些连续的1byte 是被编码的。 每个内存细胞的物理地址是唯一的,因而就容易被定位。
1. 取址运算符 &
刚刚不说了嘛,有物理地址,那取地址呢? 用它: &。 当一个变量被声明的时候,计算机根据它的类型分配相应大小的内存给它。我们要得到这个变量的值,就需要取址运算符: &。
取到了放哪呢?对了,就是指针,它专门干这事的。
2. 去址运算符 *
我能得到了变量的值的地址,同样也能得到变得的值,用什么呢? 用 *。
注意了,很多人之所以对指针会糊涂,可能就是下面的问题没有注意到。
取址运算符 & 是针对变量的
去址运算符 * 是针对指针的
你只要记住这个,你就会少糊涂点。
3. 指针声明
说了这么多用指针的话,可是在你用之前你还是要声明它的,不然编译器是不认的。指针也是变量,也有类型。所以在用的时候,请多注意了,类型要一致。
提示一下,虽然指针类型有多种,可是它们在内存中的占有的空间都是一样大的。因为它们都是指针变量。
如何声明呢?
int * pointer1;
char * pointer2;
float * pointer3;
就是这样地,不过注意,这里的 * 可不是什么去址运算符,这里表示什么的变量是指针变量。有区别的,虽然一样的表示。这也是很多人容易糊涂的地方。记住吧。
4. 指针和数组
文章开头就说了它们的相识处啊,一个是用指针,一个是用索引值。有相似处,也有不同的地方。举个例子。
int numbers [10];
int * p;
这里声明了一个数组number, 和一个指针p。 如果将数组赋值给指针是可以的。
p = number;
因为数组number 永远是指向数组的第一个元素(这里没有用索引值),这个语句也就等于说,将数组的第一个元素的地址给了指针。程序就可以对这个指针的操作来处理数据了。记住这里的指针的值是可以改变的(你可以赋另外一个值给它嘛)。
但是如果你用下面的语句,你就不对了。
number = p;
这就扯淡。为什么?
我刚刚说了,指针p是个变量,可以改变的值,而number是永远指向数组的第一个元素,是不可改变的,怎么说呢,就像一个常量指针。也就是说number是一个指针,不过是指向常量(数组的第一个元素)的指针,它的值是不可能改变的。我们不能将数值赋值给一个常量,所以是无效的语句。记住了。
5. 指针的运算
指针的运算还是有比较的区别的,相比其他正常的数据类型。因为不同类型的指针,所指向的数据在内存中占的大小是不一样的。比如说,char类型指针,指向的数据类型是1byte,short是2byte,long是4byte。那操作起来可就不一样了。
为什么?
因为指针变量存的是数据的地址。
所以当指针变量加1时,各个类型的指针指向的地方,加的地址大小就不一样了。
还有个问题,请注意
*p++;
(*p)++;
这两个的区别。++的优先级比 *大,也就是先运算++,然后才是*。
第一个语句得到的结果将不是下一个元素,而是这个元素地址在加上1后的结果,
第二个语句加了小括号,*有了优先权,指向下一个元素。
6. 指向指针的指针
什么意思?指向指针的指针就是这个指针保存来它指向的指针的地址。声明的时候,这个指向指针的指针需要多加个 *。有什么作用?不好意思,到现在为止,我没有用到过(我的程序编的少现在,有知道的人可以告诉我一声。谢谢)。
7. 空指针 (void pointer)
这个指针就好玩了,我没有类型的,也是什么类型都可能的(有点类型泛型编程的感觉),
它的作用就是传递泛型参数! 没有说到泛型编程,我就搞个例子吧,体验一把。
- //void pointer
-
#include<iostream>
-
using namespace std;
-
-
void increase (void * data, int psize) { //data这里是空指针
-
-
if (psize == sizeof(char))
-
{
-
char * prchar; pchar = (char *)data; ++ (*pchar); //看到没有,data现在是char类型的指针
-
}
-
else if (psize = sizeof (int))
-
{
-
int * pint; pint =(int *)data; ++(*pint); //这里是int类型的指针
-
}
-
}
-
-
int main () {
-
-
char a = 'x';
-
int b = 1602;
-
increase (&a, siezof(a));
-
increase (&b, sizeof(b));
-
cout<<a<<", "<<b<<endl;
-
-
return 0;
-
}
8. Null 指针 (Null pointer)
这个指针,是一个正常的指针,有类型,不像void 指针。但是它的值有点特别,是0。也就是说它不指向任何有效的地址。
int * p;
p = 0;
有什么用?我不知道,谁能告诉我?
9. 指向函数的指针
这个才有点实践的味道。指向函数的指针?什么意思?
意思就是说,函数,被指针指向的函数,可以当作参数给另外一个函数。当然也就不能做去址操作了(你想找函数的地址不成?呵呵)
声明的格式是
(* pointer)
说个例子吧
- //pointer to functions
-
#include <iostream>
-
using namespace std;
-
-
int addition (int a, int b) {
-
return (a+b);
-
}
-
-
int substraction (int a, int b) {
-
return (a-b) ;
-
}
-
-
int operation (int x, int y, int (*functocall) (int, int)) { //这里声明了一个指向函数的指针变量funtocall,并且声明了这个函数为两个参数。
-
-
int g;
-
g = (*funtocall)(x,y); //调用指针指向的函数
-
return (g);
-
}
-
-
int main () {
-
-
int m, n;
-
int (*minus) (int, int) = substraction; //将函数substraction 赋值给了指向函数的指针变量minus (函数operation声明的参数里,要指向函数的指针)
-
-
m = operation (7, 5, addition);
-
n = operation (20, m, minus); //将指向函数的指针传递给函数。
-
cout <<n;
-
return 0;
-
}
有人说,谁明白了指针,谁就明白了C, C++。这说明指针很强大,用法灵活。作用太大了。我希望今天有关指针的话没有错的地方。如果有,请大家说出来。万分感激啊。
阅读(1367) | 评论(0) | 转发(0) |