指针引入

指针:

一、声明 一个 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 assignment
    int *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=&ii;
    
    void *p1;
    p1 = p;
    
    char *pc;
    //pc = p1;
    //[Error] invalid conversion from 'void*' to 'char*' [-fpermissive]
    return 0;
}

 

 

 

posted on 2016-02-24 18:54  木鸟飞  阅读(582)  评论(1编辑  收藏  举报

导航