指针:
一、声明 一个 int 类型的 指针 然后 赋值。
二、声明中直接赋值。
三、空指针
四、悬空指针 野指针:
悬空指针本质上就是 声明了一个 指针类型的变量【如:int *p】,并且没有赋值。在没有赋初值的情况下,利用这个指针进行修改【如:*p=100】。就相当于这个指针指向了一个未知的地址。并且还做了修改。那如果这个地址是其他进程。还做了修改,就会造成系统的不稳定。因为这种不可靠的修改行为极其可怕,就好像吕伯奢开放了自己家给曹操,曹操进来以后胡乱的修改吕伯奢家人的数据,把是否存活全都置成了false.在dos版本的操作系统下,这种修改行为还是可以的。但是随着后来越来越多的黑客想要修改操作系统的数据,就相当于我操作系统很大度,开放了我自己给你,你运行了一些东西,让我这个操作系统土崩瓦解了。所以后来的操作系统做成了如下图的样子:
也就是随着后来越来越多的这种可怕行径,导致后来的法律发现如果你越界访问的话,我们就认定你是非法入室罪名。就是有一个进程不断地检测,如果 有用户进程非法访问,就立刻把这个进程从内存中清楚,以保护操作系统的稳定。所以我们现在 是可以放心做这种悬空指针的案例演示的,不过就是 我们的进程遇到了问题,被迫中止而已。这是可以接受的。
五、指针的兼容问题
以下代码:
#include <iostream>void function1(void); void function2(void); void function3(void); void function4(void); void function5(void); int main() {function5();return 0; }/**声明 一个 int 类型的 指针 然后 赋值。 */ void function1(void){int i= 10;printf("修改前i的值为:%d\n",i);int *p;//定义一个 执行int 类型的指针 变量名为p.p = &i;//取i的地址 赋给 p。*p = 100;//*p表示:访问p中的内容,根据int 这个类型,来提取这个元素。//又因为刚刚给这个里面赋了i这个值 ,所以*p 相当于i。那么i=100.//所以 *p = 100 本质上是一个赋值语句,将i的值改成了100.printf("修改后i的值为:%d\n",i); } /**声明中直接赋值。 */ void function2(void){int i =10;int *p = &i;printf("i的值为:%d\n",*p); } /**空指针 */ void function3(void){//int b = NULL;//printf("b的值为:%d\n",b);int *p = NULL;//这就是传说中的空指针,在java中报了错比较常见这个东西的,//就是因为在创建对象的时候,没有给定一个初值,导致 报了那样一个异常 printf("指针p的值为:%d,%p,%x",p,p,p); }/**悬空指针,野指针 :其实 跟function1()的内容有相像的地方,就是声明一个指针类型的变量,但是不赋值。这个 编译是可以通过的,但是运行的时候会报错。在visual studio c++ 里面编译通不过。 这是因为。谁也不知道 到底让p指向了一个什么样的内存单元。并且在不知情的情况下还给 它赋了100这个值,那这样就会极其不安全。 */ void function4(void){int *p; *p = 100;printf("悬空指针指向的地址的值是:%d\n",*p); } /**指针的兼容问题 */ void function5(void){//前面在第一个案例的时候有特意提到声明了一个 int类型的指针变量,是因为除此之外还有各种类型的指针变量。//比如:char *pc;int array[10];int *p =array;//这个我现在有点儿蒙。。。 double *pd;//也就是我们说的,先去找到那个对应的元素然后按照 char 类型取pc里面的内容 //按照double类型,取pd里面的值//所以对于指针来说 他们的大小都一样:printf("指针变量pc的大小:%d\n指针变量p的大小%d\n指针变量pd的大小%d\n",sizeof(pc),sizeof(p),sizeof(pd)); //【查看运行结果图】,会发现在这台机器里面,所有的指针变量都是8,说明这是一个64位的操作系统。//如果这些数值都是4说明这是一个32位的操作系统。所以指针变量这个值的大小是操作系统相关的。 //所以,在取值的时候需要为这个被指向的对象指明一个类型,方便在取的时候,按照合理的类型把这个元素提取出来。 // 为了继续进行先把这里注释掉,这里很关键!一定要动手尝试 //所以 如果是int *p1;char c;//p1=&c;//就会报一个这样的错误: cannot convert 'char*' to 'int*' in assignmentint *p2;unsigned int i1;//p1=&i1;//这个编译还是很严格的,就是不行。在vs里面这是被允许的。 //[Error] invalid conversion from 'unsigned int*' to 'int*' [-fpermissive]//但是 如果声明一个 指向空类型的 指针 在进行指向是被允许的。void *pv;pv=&c;pv=&i1; //这样就是编译通过的。 //p1 = pv;//[Error] invalid conversion from 'unsigned int*' to 'int*' [-fpermissive] }
上面是 main.cpp 的情况
下面是 main.c的情况:
#include <iostream>int main() {int *p;unsigned int i;//p=&i; //[Error] invalid conversion from 'unsigned int*' to 'int*' [-fpermissive]int ii;p=ⅈvoid *p1;p1 = p;char *pc;//pc = p1;//[Error] invalid conversion from 'void*' to 'char*' [-fpermissive]return 0; }