C++ 指针

2018-03-24 14:13 更新

学习C++ - C++指针

以下代码使用&运算符来查找地址。


#include <iostream> 
using namespace std; 
int main() 
{ 
     int donuts = 6; 
     double cups = 4.5; 

     cout << "donuts value = " << donuts; 
     cout << " and donuts address = " << &donuts << endl; 

     cout << "cups value = " << cups; 
     cout << " and cups address = " << &cups << endl; 
     return 0; 
} 

上面的代码生成以下结果。


例子

指针的名称代表位置。

应用*运算符在该位置产生值。


#include <iostream> 
int main() 
{ 
     using namespace std; 
     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; 
     cout << ", *p_updates = " << *p_updates << endl; 

     // 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; 
} 

上面的代码生成以下结果。

声明和初始化指针

指针声明必须指定指针指向什么类型的数据。

例如,前面的例子有这个声明:

int * p_updates;

这表示组合* p_updates是int类型。

p_updates变量本身必须是一个指针。

p_updates指向类型int。

p_updates的类型是指向int的指针,更简明地,int *。

p_updates是一个指针(地址),*p_updates是一个int而不是一个指针。

int*是一个类型,指向int。

以下声明创建一个指针(p1)和一个普通的int(p2):

int* p1, p2;

每个指针变量名称需要一个*。

以下代码演示如何初始化指向地址的指针。


#include <iostream> 
using namespace std; 
int main() 
{ 
     int higgens = 5; 
     int * pt = &higgens; 

     cout << "Value of higgens = " << higgens 
           << "; Address of higgens = " << &higgens << endl; 
     cout << "Value of *pt = " << *pt 
           << "; Value of pt = " << pt << endl; 
     return 0; 
} 

上面的代码生成以下结果。

用新的分配内存

这是一种用于获取和分配单个数据对象的内存的一般形式,它可以是一个结构以及一个基本类型,它是:

typeName * pointer_name = new typeName;

您使用数据类型两次:一次指定所请求的内存种类,一次声明一个合适的指针。


#include <iostream> 
using namespace std; 
int main() 
{ 
     int nights = 1001; 
     int * pt = new int;         // allocate space for an int 
     *pt = 1001;                 // store a value there 

     cout << "nights value = "; 
     cout << nights << ": location " << &nights << endl; 
     cout << "int "; 
     cout << "value = " << *pt << ": location = " << pt << endl; 
     double * pd = new double;   // allocate space for a double 
     *pd = 10000001.0;           // store a double there 

     cout << "double "; 
     cout << "value = " << *pd << ": location = " << pd << endl; 
     cout << "location of pointer pd: " << &pd << endl; 
     cout << "size of pt = " << sizeof(pt); 
     cout << ": size of *pt = " << sizeof(*pt) << endl; 
     cout << "size of pd = " << sizeof pd; 
     cout << ": size of *pd = " << sizeof(*pd) << endl; 
     return 0; 
} 

上面的代码生成以下结果。

通过删除释放内存

删除操作符使您能够将内存返回到内存池。

你可以使用delete来跟踪一个指向最初分配给新的内存块的指针:

int * ps = new int; // allocate memory with new 
. . .               // use the memory 
delete ps;          // free memory with delete when done 

这将删除ps点的内存。

它不会删除指针ps本身。

您可以重用ps来指向另一个新的分配。

你不应该尝试释放先前释放的内存块。

使用new创建动态数组

在C++中创建动态数组很容易;你要告诉新数组元素的类型和你想要的元素数目。

语法要求您使用括号中的元素数量来遵循类型名称。

例如,如果你需要一个10 int的数组,你可以使用:

int*psome = new int[10]; //获取10个int的块

new运算符返回块的第一个元素的地址。

在此示例中,该值分配给指针psome。

使用新增括号创建数组时,需要在释放数组时使用替代形式的delete:

delete [] psome;                  // free a dynamic array 

括号告诉C++释放整个数组,而不仅仅是指针指向的元素。

这里举个例子:

int * pt = new int; 
short * ps = new short [500]; 
delete [] pt;  // effect is undefined, don"t do it 
delete ps;     // effect is undefined, don"t do it 

不要使用delete来释放新的没有分配的内存。

不要使用delete来连续释放同一块内存两次。

如果您使用new []来分配数组,请使用delete []。

如果您使用新的分配单个实体,请使用delete(无括号)。

分配和分配数组的内存的一般形式是:

type_name * pointer_name = new type_name [num_elements]; 

例子


#include <iostream> 
using namespace std; 
int main() { 
     
     double * p3 = new double [3]; // space for 3 doubles 
     p3[0] = 0.2;                  // treat p3 like an array name 
     p3[1] = 0.5; 
     p3[2] = 0.8; 
     cout << "p3[1] is " << p3[1] << ".\n"; 
     p3 = p3 + 1;                  // increment the pointer 
     cout << "Now p3[0] is " << p3[0] << " and "; 
     cout << "p3[1] is " << p3[1] << ".\n"; 
     p3 = p3 - 1;                  // point back to beginning 
     delete [] p3;                 // free the memory 
     return 0; 
} 

上面的代码生成以下结果。

指针,数组和指针算术

C++将数组名解释为地址。


#include <iostream> 
using namespace std; 
int main() { 
     double wages[3] = {1.0, 2.0, 3.0}; 
     short stacks[3] = {3, 2, 1}; 

     // two ways to get the address of an array 
     double * pw = wages;     // name of an array = address 
     short * ps = &stacks[0]; // or use address operator 
     
     // with array element 
     cout << "pw = " << pw << ", *pw = " << *pw << endl; 
     pw = pw + 1; 
     //add 1 to the pw pointer 
     cout << "pw = " << pw << ", *pw = " << *pw << "\n\n"; 
     cout << "ps = " << ps << ", *ps = " << *ps << endl; 
     ps = ps + 1; 
     
     //add 1 to the ps pointer
     cout << "ps = " << ps << ", *ps = " << *ps << "\n\n"; 

     //access two elements with array notation
     cout << "stacks[0] = " << stacks[0] 
          << ", stacks[1] = " << stacks[1] << endl; 
     //access two elements with pointer notation
     cout << "*stacks = " << *stacks 
          << ", *(stacks + 1) =  " << *(stacks + 1) << endl; 

     cout << sizeof(wages) << " = size of wages array\n"; 
     cout << sizeof(pw) << " = size of pw pointer\n"; 
     return 0; 
} 

上面的代码生成以下结果。

指针和字符串

数组和指针之间的特殊关系扩展到C风格的字符串。请考虑以下代码:

char flower[10] = "rose"; 
cout << flower << "s are red\n"; 

数组的名称是其第一个元素的地址。

以下代码使用字符串库中的两个函数。

strlen()函数返回字符串的长度。

strcpy()函数将字符串从一个位置复制到另一个位置。


#include <iostream> 
#include <cstring>              // declare strlen(), strcpy() 
using namespace std; 

int main() { 
     char animal[20] = "C++";   // animal holds bear 
     const char * bird = "Java"; // bird holds address of string 
     char * ps;                  // uninitialized 

     cout << animal << " and ";  // display bear 
     cout << bird << "\n";       // display wren 

     cout << "Enter a kind of animal: "; 
     cin >> animal;              // ok if input < 20 chars 

     ps = animal;                // set ps to point to string 
     cout << ps << "!\n";       // ok, same as using animal 

     //Before using strcpy()
     cout << animal << " at " << (int *) animal << endl; 
     cout << ps << " at " << (int *) ps << endl; 

     ps = new char[strlen(animal) + 1];  // get new storage 
     strcpy(ps, animal);         // copy string to new storage 
     cout << "After using strcpy():\n"; 
     cout << animal << " at " << (int *) animal << endl; 
     cout << ps << " at " << (int *) ps << endl; 
     delete [] ps; 
     return 0; 
} 

上面的代码生成以下结果。

例3

以下代码使用new创建一个未命名的结构,并演示访问结构成员的两个指针符号。


#include <iostream> 
using namespace std; 
struct Product   // structure definition 
{ 
     char name[20]; 
     float volume; 
     double price; 
}; 
int main() {      
     Product * ps = new Product; // allot memory for structure 
     cout << "Enter name of Product item: "; 
     cin.get(ps->name, 20);            // method 1 for member access 
     cout << "Enter volume in cubic feet: "; 
     cin >> (*ps).volume;              // method 2 for member access 
     cout << "Enter price: $"; 
     cin >> ps->price; 
     cout << "Name: " << (*ps).name << endl;              // method 2 
     cout << "Volume: " << ps->volume << " cubic feet\n"; // method 1 
     cout << "Price: $" << ps->price << endl;             // method 1 
     delete ps;                        // free memory used by structure 
     return 0; 
} 

上面的代码生成以下结果。

例4

以下代码显示如何使用delete操作符。


#include <iostream> 
#include <cstring>      // or string.h 
using namespace std; 
char * getname(void);   // function prototype 
int main() { 
     char * name;        // create pointer but no storage 

     name = getname();   // assign address of string to name 
     cout << name << " at " << (int *) name << "\n"; 
     delete [] name;     // memory freed 

     name = getname();   // reuse freed memory 
     cout << name << " at " << (int *) name << "\n"; 
     delete [] name;     // memory freed again 
     return 0; 
} 
char * getname()        // return pointer to new string 
{ 
     char temp[80];      // temporary storage 
     cout << "Enter last name: "; 
     cin >> temp; 
     char * pn = new char[strlen(temp) + 1]; 
     strcpy(pn, temp);   // copy string into smaller space 

     return pn;          // temp lost when function ends 
} 

上面的代码生成以下结果。

以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号