• 指针和 引用 (一)


    指针和引用的区别

    1. 非空区别. 在任何情况下, 都不能使用指向空值的引用, 一个引用必须总是指向某个对象. 而指针, 可为 NULL
    2. 合法性区别. 在使用引用前不需要测试其合法性. 相反, 指针应总是被测试, 防止其为空.
    3. 可修改区别. 指针可以被重新赋值, 而引用总是在初始化时被指定对象, 以后不得修改.

     

    const 常量赋值时, 必须同时初始化.

    effective C++ 讲到 const 声明和初始化的 item2 没太看懂

     

    例题1:

    1 // p 只是一个副本
    2 void getMemory(char *p, int num) {
    3     p = (char *)malloc(sizeof(char) * num);
    4 }
    5 
    6 // p 仍是一个副本, 但 *p 不是
    7 void getMemory(char **p, int num) {
    8     *p = (char *)malloc(sizeof(char) * num);
    9 }
    

      

     

    但更一般的解法是直接让 getMemory 返回指针

    例题2:

    /*
     * str[] 是局部数组, 其有效域只在 strA 中
     */
    char *strA() {
    	char str[] = "hello world";
    	return str;
    }
    
    /*
     * char *str 分配的并不是局部数组, 而是全局数组
     */
    const char* strB() {
    	char *str = "hello world";
    	return str;
    }
    
    
    int main() {
    	char c[15] = "hello world";
    	*c = 't'; // ok
    
    	char *d = "hello";
    	*d = 't'; // wrong! 存在只读数据段
    	return 0;
    }
    

    可在 strC() 中声明一个 static char str[], 同时满足全局和可修改

     

    例题3:

     

    int main() {
    	int a[3];
    	a[0] = 0; a[1] = 1; a[2] = 2;
    
    	int *p, *q;
    	p = a;
    	q = &a[2];
    
    	cout << q-p << endl;
    
    	return 0;
    }
    

     

    p, q 的实际地址值相差是 8, 但是 q-p 的结果却是 2.

    q - p 的实际运算是 地址值之差/sizeof(int)

    例题4:

     

     

    struct S {
    	int i;
    	int *p;
    };
    
    int main() {
    	S s;
    	int *p = &s.i;
    	p[0] = 4;
    	p[1] = 3;
    
    	s.p = p;
    	s.p[1] = 1;
    	s.p[0] = 2; // 发生异常, 访问出错
    	return 0;
    }
    

     

    p[0] 就是 i, p[1] 是 *p

    s.p = p; 那么 s.p 指向 &S.i

    s.p[1] 指向 s.p, s.p[1] = 1 等价于 s.p = 1, 即现在指针 p 指向内存地址为 0x0000...1 的地方

    s.p[0] = 2 就是要访问 0x000...1空间, 对一个未做声明的空间直接访问, 所以访问出错

    例题5:

    class A {
    public:
    	int _a;
    	A() {
    		_a = 1;
    	}
    
    	void print() {
    		printf("%08x
    ",&_a);
    		printf("%d
    ", _a);
    	}
    };
    
    class B : public A {
    public:
    	int _a;
    	B() {
    		_a = 2;
    	}
    };
    
    int main() {
    	B b;
    	b.print();
    	printf("%d
    ", b._a);
    	printf("%08x
    ",&b._a);
    	return 0;
    }
    

    结果时 0x...60, 1, 2, 0x...64

    可见, 并没有发生内存覆盖.

    另外, 在 B 内另外设置一个打印函数输出 _a, 结果是 2 

     

  • 相关阅读:
    JVM调优总结(五)-分代垃圾回收详述1
    JVM调优总结(四)-垃圾回收面临的问题
    JVM调优总结(三)-基本垃圾回收算法
    JVM调优总结(二)-一些概念
    JVM调优总结(一)-- 一些概念
    ASP过滤HTML标签
    ASP防止盗链的一段代码
    通用安全字符串输入,彻底替换server.htmlencode
    ASP长文章分页的两个方法,函数
    自己用到的一个字符串替换函数
  • 原文地址:https://www.cnblogs.com/zhouzhuo/p/3639121.html
Copyright © 2020-2023  润新知