1 内存存储
- char * p = "hello,world";
对于个语句中,p所占的内存空间是分配在栈空间中的,在变量p的生命期结束时自动释放,其中"hello,world";是存在全局的静态区的,是到这个程序才会释放的空间。当p的生命期结束后,我们将无法访问到存储"hello,world"的那块内存。所以对一下应用将会是一个错误的决定:
- char *strA()
- {
- char str[] = "hello,world";
- return str;
- }
2 指针的内存分配应由编译器进行
我们不能随便为一个指针指定内存,那样是非常危险的,因为我们根本无法确定这个内存地址是否在使用,或是是一个很重要的内存空间。如:
- int *p;
- p = (int*)0x8000;
- *p = 2;
将会出现执行期错误。
3 通过一个结构体来探索指针
- #include <iostream>
- using namespace std;
- struct stu
- {
- int i;
- int *p;
- };
- int main()
- {
- stu a;
- int *p = &a.i;
- p[0] = 4;
- p[1] = 5;
- cout << a.i << endl;
- cout << *(&a.i + 1) << endl;
- cout << &a.p << endl;
- cout << (&a.i + 1) << endl;
- a.p = p;
- a.p[1] = 1;
- a.p[0] = 2;//出现运行期错误
- return 0;
- }
首先我们定义了一个结构体对象a,那么现在我们就拥有了两个int型的内存,一个是为i分配的,一个是为结构体中的int型指针分配的。现在我们只有操作这两个int的内存为合法的。其他的均属于未定义行为,会引起运行期错误。
int *p = &a.i; //令p指向我们拥有的那两个int型内存的起始地址.
p[0] = 4; // ok 操作第一个int型内存 ,现在a.i = 4;
p[1] = 5; // ok 操作第二个int型内存.现在a.p中存储的应该就是5了。对此我们可以利用下面语句验证。
- cout << int(a.p) << endl;
为了跟进一步的验证,我们使用了下列语句:
- cout << &a.p << endl;
- cout << &a.i + 1 << endl;
说明了结构体中的p所占的空间和i是连续的下一个空间。然后我们就可以通过i的内存地址来访问到p的地址。进而输出p[1];
- cout << *(&a.i + 1) << endl;
而对于程序中的:
- a.p = p;
- a.p[0] = 2;
- a.p[1] = 1;
令a.p 存储结构体的首地址。
a.p[0] = 2; //ok 令a.i = 2;
a.p[1] = 1; //ok 令第二个可操作int空间的值为1.此时a.p = 1;
但此刻我们不能在操作a.p[0],a.p[1].否则会出现运行期错误。
4
- float(**def)[10];
它是一个二级指针,指向一个指向一个含有10个元素的一位数组的指针。其实我们可以把def理解为一个三维数组名。即我们可以认为我们现在定义了一个三维数组,数组名为def。不过这个三维数组只有一行。10列。呵呵。。我们可以通过下列程序验证:
- float(**def)[10];
- float a[10] = {1,2,7};
- float (*f)[10];
- f = &a;
- cout << *a << endl;
- cout << f[0][0] << endl;
- cout << f[0][1] << endl;
- cout << f[0][2] << endl;
- def = &f;
- cout << def[0][0][0] << endl;
- cout << def[0][0][1] << endl;
- cout << def[0][0][2] << endl;
- #include <iostream>
- using namespace std;
- int main()
- {
- float(**def)[10];
- float a[10] = {1,2,7};
- float (*f)[10];
- f = &a;
- cout << a << endl;
- cout << (*f)[0] << endl;
- cout << (*f)[1] << endl;
- def = &f;
- cout << (**def)[0] << endl;
- cout << (**def)[1] << endl;
- return 0;
- }
5
- double (*f[10])();
一个函数指针数组。即f 是一个拥有10个函数指针的数组,该函数指针指向返回类型为double,参数为空的函数。
6
- double *(*gh)[10]
gh 是一个指针,它指向一个一维数组,数组的元素都是double *。
7
- int (*(*fun)(int,int))(int);
fun是一个函数指针,它指向含有两个int型参数并返回一个函数指针的函数。返回的函数指针类型为返回类型为int型,参数为int。