[title]什么是指针[/title]
我们如何得到常规变量的地址呢?我们只需对变量应用地址运算符(&),就可以以获得它的位置;例如,如果home是一个变量,则&home是它的地址。
使用常规变量时,值是指定的量,地址是派生量;
而指针变量恰恰相反,地址是指定量,值是派生量。
指针名表示地址。*运算符被称为简介值或解除引用运算符,将其应用于指针,可以得到改地址处存储的值。下面是具体的使用。
#include <iostream> using namespace std; int main(){ int updates = 6; // declare a variable int *p_updates; //declare pointer to an int p_updates = &updates; // assign address of int to pointer //express values two ways cout << "Values: updates = " <<updates; // value = 6 cout << ", *p_updates = " << *p_updates <<endl; // value = 6 //express address two ways cout << "Addresses: &updates = " << &updates; cout << ", p_updates = " << p_updates << endl; //use pointer to change value *p_updates = *p_updates + 1; cout << "Now updates = " << updates <<endl; return 0; }
[title]申明和初始化指针[/title]
申明指针:
ps:*旁的空格是可选的;
typeName *pointer_name;
初始化指针:
ps:1.指针的地址长度都是相同的(具体的取决于计算机系统)
2.初始化的是指针pt,不是它(*pt)指向的值
3.初始化的时候应该赋给它的是地址而不是值,这发生最隐匿、最难以跟踪的bug;
int higgens = 5; int *pt = &higgens;
[title]指针和数字[/title]
如果我们一定要将数字作为地址来使用辣么,应该通过强制转换,例如下
int *pt; pt = (int *) 0xB8000000; // types now match
[title]使用new来分配内存[/title]
在C语言中,可以库函数malloc()来分配内存;在C++中我们可以用new运算符
通用格式如下
typeName *pointer_name = new *typeName;
我们告诉new,需要哪种数据类型分配内存;new找到一个长度正确的内存块,并返回内存块的地址。我们只要将该地址赋给一个指针就OK了;
[title]使用delete释放内存[/title]
delete运算符在使用完内存后,能够将其归还给内存池,具体用法: delete(pointer_name)
这里我们要注意的是:
1、释放内存,但不会删除指针本身
2、delete和new一定要搭配使用(就是delete只能释放使用new分配的内存,但对空指针使用delete是Ok的),否则会发生内存泄漏问题
3、释放过的内存块不能再释放
4、不能使用delete来释放申明变量所获得的内存
5、如果使用new[]为数组分配内存,则应使用delete[]来释放。
int * ps = new int; // ok delete ps; // ok delete ps; // not ok now int jugs = 5; // ok int *pi = &jugs //ok delete pt; // not allowed, memory not allocated by new
[title]使用new来创建动态数组[/title]
就是使用new,如果在运行阶段 需要数组,就创建 它;不需要就不创建;就叫动态数组
为数组分配内存的通用格式如下:
type_name *pointer_name = new type_name[num_elements]; // 第一个元素的地址赋给指针
创建了动态数组后,我们如何访问其中的元素呢?
只要把指针当做数组名使用就可以,对于第一个元素可以使用pointer_name[o], 而不是*poiter_name, 第二个就是pointer_name[1],一次类推
[title]指针、数组和指针算术[/title]
C++中将数组名解释为地址,数组名为第一个元素的地址
double *pw = wages; // wages为数组名 wages = &wages[0] = address of first elements of array
由于pw指向第一个元素,因此*pw显示的是第一个元素的值,这里唯一的区别是我们可以修改指针的值,而数组名是常量,另一个区别是,对数组使用sizeof 得到的是数组的长度,而对指针使用的到的是指针的长度;
数组名被解释为第一个元素的地址,而对数组名应用地址运算符时,得到的是整个数组的地址;
指针算术:
C++允许指针和整数想家,加K的结果是原来的地址值加上指向的对象占用的总字节数。还可以将一个执政减去另一个指针,获得两个指针的差,它会得到一个整数,仅当两个指针指向同一个数组才有意义,得到两个元素的间隔。
int tacos[10] = {5, 2, 8, 4, 1, 2, 2, 4, 6, 8}; int *pt = tacos; //suppose pf and tacos are the address 3000 pt = pt + 1; // now pt is 3004 if a int is 4 bytes int *pe = &tacos[9]; // pe is 3036 if an int is 4 bytes pe = pe - 1; // now pe is 3032, thie address of tacos[8] int diff = pe - pt; // diff is 7, thie separation between // tacos[8] and tacos[1]
[title]指针和字符串[/title]
cout对象认为char的地址是字符串 的地址,因此它打印该地址处的字符,然后继续打印后面的字符,直到遇到空字符(\0)位置。
在C++中,用引号括起的字符串像数组名一样,也是第一个元素的地址。
注意:在cout和多数C++表达式中,char数组名、char指针以及用引号括起的字符串常量都被解释为字符串的第一个字符的地址。
经常要将字符串放到 数组中。初始化数组时,要使用=运算符,苟泽使用strcpy或strncpy()
char food[20] = "carrotes"; // initialization strcpy(food, "flan"); // otherwise
但如果food数组比字符串要小,就会出现问题
这时我们就要用strncty(),如果该函数在到达字符串结尾之前,目标内存已经用完,则它将不会添加空字符,此时就该这样做,如下
strncpy(food ,"aaaaaaaaaaaaaaaaaaaaaaaaaaa", 19); food[19] = '\0';
这样最多将19个字符复制到数组中,然后将最后一个元素设置成空字符。如果该字符少于19个字符,则复制完它后加上空字符,以标记该字符串的结尾。