C++指针
说到指针我们就不得不提一提内存:在c++程序中每一个变量都是存在于内存中,而指针就是地址;每一个变量都有一个内存位置,每一个内存位置都定义了可使用连字号(&)运算符访问的地址,它表示了在内存中的一个地址。
指针申明:
int *ip; /* 一个整型的指针 */ double *dp; /* 一个 double 型的指针 */ float *fp; /* 一个浮点型的指针 */ char *ch; /* 一个字符型的指针 */
所有指针的值的实际数据类型,不管是整型、浮点型、字符型,还是其他的数据类型,都是一样的,都是一个代表内存地址的长的十六进制数。不同数据类型的指针之间唯一的不同是,指针所指向的变量或常量的数据类型不同
假如我们定义一个:int i=20;
int *p;表示定义一个p指针,p中存放的是一个内存地址;
p=&i:就表示我们将i这个变量存放的地址取出来赋值给p;
给出一下一小段程序:
int main()
{
int i = 20;
int *p;
p = &i;
cout << *p << " " << &i << endl;
}
运行过后结果为:
在上面的代码中:p是地址;*p是将p这个地址中的值取出来;所以*p的值是20;&i是i的地址;
空指针:
在变量声明的时候,如果没有确切的地址可以赋值,可以为指针变量赋一个 NULL 值。赋为 NULL 值的指针被称为空指针。
NULL 指针是一个定义在标准库中的值为零的常量。
int main()
{
int *p= NULL;
cout << p << " "<< endl;
}
运行结果为:
在大多数的操作系统上,程序不允许访问地址为 0 的内存,因为该内存是操作系统保留的。然而,内存地址 0 有特别重要的意义,它表明该指针不指向一个可访问的内存位置。但按照惯例,如果指针包含空值(零值),则假定它不指向任何东西。
如需检查一个空指针,您可以使用 if 语句,如下所示:
if(p)
if(!p)
数组指针:
指针和数组是密切相关的。事实上,指针和数组在很多情况下是可以互换的。例如,一个指向数组开头的指针,可以通过使用指针的算术运算或数组索引来访问数组。
int main()
{
int var[4] = { 3,2,3,4 };
int *p= NULL;
p = var;
for (int i = 0; i < 4; i++)
{
cout << *p << endl;
p++;
}
}
结果为:
把指针运算符 * 应用到 var 上是完全可以的,但修改 var 的值是非法的。这是因为 var 是一个指向数组开头的常量,不能作为左值。由于一个数组名对应一个指针常量,只要不改变数组的值,仍然可以用指针形式的表达式。
传递指针给函数:
c++也可以给函数传入指针:
#include <iostream>
using namespace std;
double getAverage(int *arr, int size);
void main()
{
int var[4]={3,3,2,4};
int k;
k=getAverage(var, 4);
cout<<k<<endl;
}
double getAverage(int *arr, int size)
{
int i, sum = 0;
double avg;
for (i = 0; i < size; ++i)
{
sum += arr[i];
}
avg = double(sum) / size;
return avg;
}
代码结果为:
二级指针:
二级指针就是指针的指针,如图:
例子:
int main()
{
int var[4] = {3,2,3,4};
int *p;
int **Ptr;
p=var;
Ptr=&p;
for(int i=0;i<4;i++)
{
cout<<*p<<endl;
p++;
//cout << **Ptr << endl;
//(*Ptr)++;
}
}
输出结果: