C++ 指针 (重要)这是关于动态内存分配的一个关键
C++ 的指针可以简化一些 C++ 编程任务的执行,如动态内存分配,每一个变量都有一个内存位置,每一个内存位置都定义了可使用连字号(&)运算符访问的地址,它表示了在内存中的一个地址。
常见的访问方式:
#include <iostream>
using namespace std;
int main ()
{
int var1; //整数型
char var2[10]; //字符串型
cout << "var1 变量的地址: ";
cout << &var1 << endl; //&var1即访问var1的内存地址
cout << "var2 变量的地址: ";
cout << &var2 << endl;
return 0;
}
指针:一个变量,其值为内存位置的直接地址。要使用指针储存其他变量地址之前,需要对其进行声明,格式为:
type *var-name; //type为指针的基类型(数据类型),var-name是容器的名字
//例如
int *ip; //一个整型的指针
double *dp;
char *ch;
需要注意的是所有指针的值实际数据类型,不管是int、double、float、char还是其他的,都是一样的,都是一个代表内存地址的长的十六进制数。不同数据类型的指针之间唯一的不同是,指针所指向的变量或常量的数据类型不同。
#include <iostream>
using namespace std;
int main ()
{
int var = 20; // 实际变量的声明
int *ip; // 指针变量的声明
ip = &var; // 在指针变量中存储 var 的地址
cout << "Value of var variable: ";
cout << var << endl;
// 输出在指针变量中存储的地址
cout << "Address stored in ip variable: ";
cout << ip << endl;
// 访问指针中地址的值
cout << "Value of *ip variable: ";
cout << *ip << endl;
return 0;
}
C++ Null 指针:C++ 支持空指针,在变量声明的时候,若无确切的地址可以赋值,为指针变量赋一个 NULL 值是一个良好的编程习惯。
#include <iostream>
using namespace std;
int main ()
{
int *ptr = NULL; //在标准库里面,NULL指针是一个定义在标准库中的值为零的常量
cout << "ptr 的值是 " << ptr ;
return 0;
}
C++ 指针的算术运算:可以对指针进行四种算术运算:++、–、+、-
#include <iostream>
//在用指针替代数组时,一定要知道变量指针使可以递增的,但是数组却无法递增(因为是一个常量指针)
//下面为递增与递减的实例
//下面对其进行指针与数组互换
using namespace std;
const int MAX = 3; //让下面叠加一次即可
int main()
{
int var[MAX] = {10, 100, 200};
int *ptr;
// 指针中的数组地址
ptr = var;//递增
//ptr = &var[MAX-1]; //递减
for (int i = 0; i < MAX; i++//i--)
{
cout << "Address of var[" << i << "] = ";
cout << ptr << endl;
cout << "Value of var[" << i << "] = ";
cout << *ptr << endl;
// 移动到下一个位置
ptr++;
//ptr--
}
return 0;
}
#include <iostream>
//指针可以用关系运算符进行比较,如 ==、< 和 >。如果 p1 和 p2 指向两个相关的变量,比如同一个数组中的不同元素,则可对 p1 和 p2 进行大小比较。
using namespace std;
const int MAX = 3;
int main ()
{
int var[MAX] = {10, 100, 200};
int *ptr;
// 指针中第一个元素的地址
ptr = var;
int i = 0;
while ( ptr <= &var[MAX - 1] ) //若变量地址指向的地址小于或等于数组的最后一个元素的地址,则进行递增
{
cout << "Address of var[" << i << "] = ";
cout << ptr << endl;
cout << "Value of var[" << i << "] = ";
cout << *ptr << endl;
// 指向上一个位置
ptr++; //递增
i++;
}
return 0;
}
**C++ 指针数组:**可以定义用来存储指针的数组。
可以参考C++ 指针的算术运算,下面为简化的
#include <iostream>
using namespace std;
const int MAX = 3;
int main ()
{
int var[MAX] = {10, 100, 200};
for (int i = 0; i < MAX; i++)
{
cout << "Value of var[" << i << "] = ";
cout << var[i] << endl;
}
return 0;
}
当然也可以用一个指向字符的指数数组来存储一个字符串列表
#include <iostream>
using namespace std;
const int MAX = 4;
int main ()
{
const char *names[MAX] = { //字符串声明
"Zara Ali",
"Hina Ali",
"Nuha Ali",
"Sara Ali",
};
for (int i = 0; i < MAX; i++)
{
cout << "Value of names[" << i << "] = ";
cout << names[i] << endl;
}
return 0;
}
C++ 指向指针的指针: C++ 允许指向指针的指针(指针链)。
#include <iostream>
using namespace std;
int main ()
{
int var; //整数声明
int *ptr; //指针指向
int **pptr; //指针指向指针
var = 3000;
// 获取 var与ptr的地址
ptr = &var;
pptr = &ptr;
// 使用 pptr 获取值
cout << "var 值为 :" << var << endl;
cout << "*ptr 值为:" << *ptr << endl;
cout << "**pptr 值为:" << **pptr << endl;
cout << "var 地址为 :" << &var << endl;
cout << "ptr=&var 值为var的地址:" << ptr << endl;
cout << "ptr地址为:" << &ptr << endl;
cout << "*pptr=ptr=&var 值为var的地址:" << *pptr << endl;
cout << "pptr 地址为:" << &pptr << endl;
return 0;
}
**C++ 传递指针给函数:**通过引用或地址传递参数,使传递的参数在调用函数中被改变。
#include <iostream>
#include <ctime>
//传递一个无符号的 long 型指针给函数,并在函数内改变这个值
using namespace std;
void getSeconds(unsigned long *par);
int main ()
{
unsigned long sec;
getSeconds( &sec );
// 输出实际值
cout << "Number of seconds :" << sec << endl;
return 0;
}
void getSeconds(unsigned long *par)
{
// 获取当前的秒数
*par = time( NULL );
return;
}
C++ 从函数返回指针: C++ 允许函数返回指针到局部变量、静态变量和动态内存分配。
#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;
// 要生成和返回随机数的函数
int * getRandom( )
{
static int r[10];
// 设置种子
srand( (unsigned)time( NULL ) );
for (int i = 0; i < 10; ++i)
{
r[i] = rand();
cout << r[i] << endl;
}
return r;
}
// 要调用上面定义函数的主函数
int main ()
{
// 一个指向整数的指针
int *p;
p = getRandom();
for ( int i = 0; i < 10; i++ )
{
cout << "*(p + " << i << ") : ";
cout << *(p + i) << endl;
}
return 0;
}