1.对于如下代码:
char flower[10]="rose";
cout<
数组名是第一个元素的地址,因此cout语句中的flower是包含字符r的char元素的地址。也就是说,cout在遇到char类型字符时,打印的是该处地址的字符直到遇到空字符结束。但若是遇到其他类型地址,则cout打印的是地址本身。
在C++中,用引号括起的字符串像数组名一样,也是第一个元素的地址。
上诉两者本身传递给cout的是地址。
以下代码展示了字符串和指针的使用:
#define _CRT_SECURE_NO_WARNINGS
#include
#include
using namespace std;
int main()
{
char animal[20] = "bear";
const char* bird = "wren";
char* ps;
cout << animal << " and " << bird << endl;
cout << "Enter a king of animal:";
cin>>animal;
cout << bird << endl;
cout << animal << endl;
ps = animal;
cout << ps << endl;
cout << animal << " at " << &animal << endl;
cout << ps << " at " << (int*)ps << endl;
cout << "After using strcpy\n";
ps = new char[strlen(animal) + 1];
strcpy(ps, animal);
cout << animal << " at " << &animal << endl;
cout << ps << " at " << (int*)ps << endl;
delete[]ps;
return 0;
}
另外,对于字符串的拷贝strcpy(),如果参数ps的所指的内存空间不够大,可能会造成缓冲溢出的错误。因此我们能用strncpy()来替代,这样就不会出现缓冲溢出的问题,但两者都具有不安全性。
2.使用new创建动态数组。
在运行时创建数组优于在编译时创建数组,对于结构也是如此。需要在程序运行时为结构分配所需的空间,这也可以使用new运算符来完成。通过使用new,可以创建动态结构。同样,“动态”意味着内存是在运行时,而不是编译时分配的。由于类与结构非常相似,因此本节介绍的有关结构的技术也适用于类。将new用于结构由两步组成:创建结构和访问其成员。要创建结构,需要同时使用结构类型和new.例如,要创建一个未命名的inflatable类型,并将其地址赋给一个指针,可以这样做:
inflatable * ps= new inflatable;
这将把足以存储inflatable结构的一块可用内存的地址赋给ps。这种句法和C++的内置类型完全相同。比较棘手的一步是访问成员。创建动态结构时,不能将成员运算符句点用于结构名,因为这种结构没有名称,只是知道它的地址。C++专门为这种情况提供了一个运算符:箭头成员运算符(->)。该运算符由连字符和大于号组成,可用于指向结构的指针,就像点运算符可用于结构名一样。例如,如果ps指向一个aflatable结构,则ps->price是被指向的结构的price成员。
如下代码展示了如何用指针访问结构体成员:
#include
using namespace std;
struct inflatable
{
char name[20];
float volume;
double price;
};
int main()
{
inflatable* ps = new inflatable;
cout << "Enter name of inflatable item:";
cin.get((* ps) .name, 20);
cout << "Enter volume in cubic feet:";
cin >> (*ps).volume;
cout << "Enter price $";
cin >> ps->price;
cout << "Name:" << (*ps).name << endl;
cout << "Volum:" << ps->volume << endl;
cout << "Price: $" << ps->price << endl;
delete ps;
return 0;
}
3.一个使用new和delete的示例。
该程序用来存储通过键盘输入的字符串的示例。定义一个函数getname(),该函数返回一个指向输入字符的指针。该函数将输入读入到一个大型数组中,然后使用new[]创建一个刚好能够存储该输入字符的内存块,并返回一个指向该内存块的指针。
#define _CRT_SECURE_NO_WARNINGS
#include
#include//用了strlen和strcpy
using namespace std;
char* getname();//声明一个getname()函数
int main()
{
char* name;//要将getname()返回值赋给name指针
name=getname();//调用getname()函数
cout << name <<" at "<<(int *)name<< endl;
delete[]name;//释放内存空间
return 0;
}
char* getname()
{
char tmp[80];//用于存放输入的字符串
cout << "Enter last name:";
cin.get(tmp, 80);//将输入读入到临时数组之中
char* pn = new char[strlen(tmp)+1];//用new创建刚好读入该字符串的内存空间
strcpy(pn, tmp);//将tmp中的内容拷贝到开辟出来的内存空间
return pn;//返回到指向该内存块的指针
}
4.自动存储,静态存储和动态存储。
C++有三种管理数据的方式。
在函数内部定义的常规变量使用自动存储空间。这意味着它们在所属的函数被调用时自动产生,在该函数结束时消亡。实际上,自动变量是一个局部变量,其作用域为包含它的代码块,代码块是被包含在花括号中的一段代码。自动变量通常储存在栈中,这意味着执行代码时,其中的变量将依次加入到栈之中,而在离开代码块时,将按相反的顺序释放这些变量。,这被称为后进先出。因此,在程序执行之中,栈将不断地缩小增大。
静态存储是整个程序在运行期间都存在的存储方式。使变量成为静态的方式有两种:一种是爱函数外面定义它,另一种是声明时使用关键字static:
static double fee=56.50;
new和delete运算符提供了一种比自动变量和静态变量更灵活的方法。他们管理了一个内存池(堆)。
栈和堆的内存泄露:在使用new运算符船舰了一段内存空间,但并未调用delete释放掉其内存,则即使包含指针的内存由于作用域规则和对象生命周期而被释放掉,在自由存储空间上动态分配的变量或结构也将继续存在。实际上,将会无法访问自由存储空间中的结构,因为指向这些内存的指针无效。这将导致内存泄漏。被泄露的内存在整个程序生命周期都无法使用,及内存被分配出去,但无法收回,这个问题很严重!