指针与引用

指针与引用的差别:
1.非空区别。在任何情况下,都不能使用指向空值的引用。
2.合法性区别。在使用引用之前不需要测试它的合法性,指针则应该总是被测试,防止其为空。
3.可修改区别。指针可以被重新赋值以指向另一个不同的对象,而引用则只能指向初始化时被指定的对象。
4.可计算区别。指针可以进行加减运算,引用则不行。
例题1
这个函数有什么问题,该如何修改?
char *strA()
{
    char str[] = "hello world";
    return str;
}
分析:“hello word"存储在堆栈中,为局部变量,函数调用完成时会被释放,存放”hello world“的空间不应再被访问。可修改为:
const char *strA()
{
    char* str = "hello world";
    return str;
}
char c[] = "hello world"是分配一个局部数组,而char *c = "hello world"是分配一个全局数组。局部数组是局部变量,它对应内存中的栈。全局数组是全局变量,它对应内存中的全局区域。
char * c = "hello world",字符串在静态存储区,不可以通过c[0]='a'来修改。
char c[]= "hello world",可以通过c[0]='a'来修改。
上述代码也可以换成:
const char *strA()
{
    static char str[] = "hello world";//开辟一段静态存储区
    return str;
}
答案:因为这个函数返回的是局部变量的地址,当函数调用完成后,这个局部变量就释放了,所以返回的结果是不确定的,不安全的,随时都有被收回的可能。
 
例题2
请问下面代码的输出结果是多少?
 
分析:首先要先判断p->fun()调用的是哪个类中的函数,根据指针类型,它调用的应该是B类中的函数,但是p所指向的内存空间中
并没有变量C。事实上,编译器对c的认识就是变量c相对于对象的首地址的偏移量,而c的偏移量为0,因此会打印出偏移a首地址为0的
数据。
答案:1(a的值)
 
例题3
下面程序会在哪一行崩溃?
s.p[1]=1将s.p的值修改为1,因此s.p[0]=2,相当于*((int * )1) = 2;也就是要访问0x00000001空间,对一个未做声明的地址空间进行访问,会出现访问出错。测试代码如下:
答案:s.p[0] = 2 崩溃。
posted @ 2015-07-09 21:35  Rosanne  阅读(203)  评论(0编辑  收藏  举报