Cpp 指针常见用法
C++的指针的正确理解:指针是一种特殊的变量,该变量存放的是内存地址。
值得一提的是,本博客阐述了多个****************
的原理
1、用于变量
变量指针常用在函数的形参中,如经典的swap函数,用于交换两个变量的值。
#include<iostream>
void swap(double* a,double* b)
{
double temp = *a;
*a = *b;
*b = temp;
}
int main(int argc, char** argv)
{
double a, b;
a = 1, b = 2;
printf("交换前:a=%f,b=%f\n", a, b);
swap(&a, &b);
printf("&a的类型为(%s)\n", typeid(&a).name());
printf("交换后:a=%f,b=%f\n", a, b);
std::cin.get();
return 0;
}
根据输出结果可以知道,&a实质上为(doubel*)的指针类型,传入swap函数中时摆脱了局部变量的限制。
2、用于一维数组
#include<iostream>
void main(int argc, char** argv)
{
double a[3] = {1.3,2.6,3.13};
printf("a的类型为:%s\n", typeid(a).name());
double* pa = a;
for (int i = 0; i < 3; i++) { printf("a[%d]=%f\n",i,*(pa+i)); }
printf("pa的类型为:%s\n", typeid(pa).name());
std::cin.get();
return;
}
3、用于二维数组
#include<iostream>
void main(int argc, char** argv)
{
double a[2][2] = { {11.00,12.00},{21.00,22.00} };
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 2; j++)
{
printf("a[%d][%d]=%f\t", i, j, *(*(a + i) + j));
}
printf("\n");
}
double *pa = *a;
printf("pa的类型为:%s\n", typeid(pa).name());
printf("**a的类型为:%s\n", typeid(**a).name());
printf("*a的类型为:%s\n", typeid(*a).name());
printf("a的类型为:%s\n", typeid(a).name());
printf("pa[0]=%f,pa[1]=%f\n", pa[0], pa[1]);
printf("**a=%f,\t*(*a+1)=%f\n", **a, *(*a + 1));
std::cin.get();
}
4、用于类
main.cpp
#include<iostream>
#include<cmath>
#include"MyClass.h"
int main(int argc, char**argv)
{
MyClass *pmc;
pmc = new MyClass(2);
std::cout << sqrt(pmc->r2(3,4))<<std::endl;
delete pmc; //验证析构函数是否被调用
std::cin.get();
return 0;
}
MyClass.h
#pragma once
#include<iostream>
class MyClass
{
public:
MyClass();
MyClass(double a);
double r2(double x, double y);
~MyClass();
double ca;
private:
};
MyClass.cpp
#include"MyClass.h"
MyClass::MyClass()
{
}
MyClass::MyClass(double a)
{
ca = a;
}
double MyClass::r2(double x, double y)
{
return x*x + y*y;
}
MyClass::~MyClass()
{
printf("析构函数被调用了");
}
5、函数指针类型
- 范例1
// 函数作为另外一个函数的参数
#include<iostream>
double fun(double x, double y)
{
return x + y;
}
//******************************************
double fun1(double x, double y,double (*f)(double,double))
{
return (*f)(x, y);
}
//******************************************
void main(int argc, char** argv)
{
double (*pf)(double x, double y)=fun;
printf("fun的类型为%s\n", typeid(fun).name());
printf("*pf的类型为%s\n", typeid(*pf).name());
printf("pf的类型为%s\n", typeid(pf).name());
printf("(*pf)(1, 1)=%f\n", (*pf)(1, 1));
printf("fun1(1,1,fun)=%f", fun1(1, 1, fun));
std::cin.get();
return;
}
- 范例2
// 函数作为另外一个函数的参数
#include<iostream>
class MyClass
{
public:
static void printhhh() { std::cout << "哈哈哈\n"; };
static void p1(void f()) { f(); };
private:
};
//******************************************
void main(int argc, char** argv)
{
MyClass::p1(&MyClass::printhhh);
printf("%s", typeid(&MyClass::printhhh).name());
std::cin.get();
return;
}
6、多级指针
拿经典的**举例:
double ** ppa;
ppa的类型为 double**,它可以指向指针的指针。
如double b=1;
double* pb=&b;
ppa=&pb;
这样就实现了ppa指向pb,**ppa存放的是b的值。
假设存在一个二维数组a[6][2]
,那么二维数组各个元素的地址如图所示:
下列代码可以验证上面的推理:
#include<iostream>
using namespace std;
int main()
{
double a[6][2] = { };
for (int i = 0; i < 6; i++)
{
for (int j = 0; j < 2; j++)
{
printf("&(a[%d][%d])=%p\t", i, j, &a[i][j]);
}
printf("\n");
}
printf("****************************************\n");
for (int i = 0; i < 6; i++)
{
for (int j = 0; j < 2; j++)
{
printf("*(a + %d) + %d=%p\t", i, j, *(a + i) + j);
}
printf("\n");
}
std::cin.get();
return 0;
}
验证结果如下,与推理完全吻合:
最后来一段应用多级指针应用的代码:
#include<iostream>
int main(int argc, char** argv)
{
double a = 666.666;
double* pa = &a;
double** ppa = &pa;
double*** pppa = &ppa;
printf("ppa类型为%s,pppa类型为%s\n", typeid(ppa).name(),typeid(pppa).name());
printf("**ppa=%f\n***pppa=%f\n", **ppa, ***pppa);
std::cin.get();
return 0;
}