指针和 引用 (一)

指针和引用的区别

  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 

 

原文地址:https://www.cnblogs.com/zhouzhuo/p/3639121.html