您的位置:首页 > 其它

指针引入

2016-02-24 18:54 351 查看
指针:

一、声明 一个 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=ⅈ

void *p1;
p1 = p;

char *pc;
//pc = p1;
//[Error] invalid conversion from 'void*' to 'char*' [-fpermissive]
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: