C++指针和字符串

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成员。

C++指针和字符串_第1张图片

如下代码展示了如何用指针访问结构体成员:

#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释放掉其内存,则即使包含指针的内存由于作用域规则和对象生命周期而被释放掉,在自由存储空间上动态分配的变量或结构也将继续存在。实际上,将会无法访问自由存储空间中的结构,因为指向这些内存的指针无效。这将导致内存泄漏。被泄露的内存在整个程序生命周期都无法使用,及内存被分配出去,但无法收回,这个问题很严重!                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                

你可能感兴趣的:(C++,c++,开发语言)