/*
A、变量指针 :指向变量的指针
B、指针变量 :指针是一个变量
C、常量指针 :指向常量的指针
D、指针常量 :指针是一个常量
E、数组指针 :指向数组的指针
F、指针数组 :以指针为元素的数组
G、函数指针 :指向函数的指针
H、指针函数 :返回值为指针的函数
I、行指针 :int (*a)[n];
J、列指针 : 就是普通的指针
K、二级指针 :指向指针的指针
L、空指针 :void * p;
M、野指针 : 指向非法地址的指针
N、NULL指针 :指向NULL地址的指针
*/
#include<cstdio>
#include<iostream>
#include<cstdlib> //malloc()
using namespace std;
template<class T>
void Print(string str, T t){
cout<<str<<": "<<t<<endl;
}
void fun(int x,int y){
Print("x", x);
Print("y", y);
}
int* functionReturningAddress(){
int * a = (int*)malloc(sizeof(int));
*a = 123456;
return a; //返回int型地址
}
int main(){
int a;
//A、变量指针 :指向变量的指针(T* t) //T refers to Type
int *pa = &a;
//B、指针变量 :指针是一个变量(T* t)
int *p;
//C、常量指针 :指向常量的指针(const T *t)
const int b=0;
const int *pb = &b;
// *pb = 1; //error: 不可以修改整形常量的值
//D、指针常量 :指针是一个常量 (T * const t)
int x,y;
int * const px = &x;
// px = &y; //error:不可以修改指针常量的值
//E、数组指针 :指向数组的指针
int c[10]={1,2,3};
int *pc = c;
Print("pc[3]",pc[3]);
//F、指针数组 :以指针为元素的数组
int d0=1,d1=2,d2=3;
int *pd[3];
pd[0] = &d0;
pd[1] = &d1;
pd[2] = &d2;
//将输出d0,d1,d2的值
Print("*pd[0]", *pd[0]);
Print("*pd[1]", *pd[1]);
Print("*pd[2]", *pd[2]);
//将输出d0,d1,d2的地址
Print("pd[0]", pd[0]);
Print("pd[1]", pd[1]);
Print("pd[2]", pd[2]);
//输出d0,d1,d2的地址
Print("&d0",&d0);
Print("&d1",&d1);
Print("&d2",&d2);
//G、函数指针 :指向函数的指针
void (*pf)(int,int) = fun;
pf(10,28); //相当于直接调用函数fun(10,28);
//H、指针函数 :返回值为指针的函数
int *pe = functionReturningAddress();
Print("pe",pe);
Print("*pe",*pe);
free(pe); //Notice: remember to free the memory using free(ptr)
//I、行指针 :int (*a)[n]; //行指针指向二维数组的某一行,n代表二维数组第二维的大小
int g[2][3]={1,2,3,4,5,6};
int h[2][4]={1,2,3,4,5,6};
int (*pg)[3];//定义一个能指向二维数组第二维大小为3的行指针
pg = &g[1];
Print("pg",pg);
Print("pg[0]",pg[0]);
Print("pg[0][0]",pg[0][0]);
// pg = &h[1]; //error: can't covert int(*)[4] to int(*)[3]
//J、列指针 : 就是普通的指针
int *pj = &g[1][2]; //列指针指向二维数组的某一个元素,就是普通指针而已
Print("*pj",*pj);
//K、二级指针 :指向指针的指针
int z=10;
int *pz = &z; //pz是一级指针,指向相同类型的变量
int **ppz = &pz;//ppz是二级指针,指向相同类型的一级指针
Print("&z",&z); //输出z的地址
Print("z",z); //输出z的值
Print("pz",pz); //输出z的地址
Print("*pz",*pz); //输出z的值
Print("pz",pz); //输出pz的值,也就是z的地址
Print("&pz",&pz); //输出pz的地址(一级指针变量的地址)
Print("ppz",ppz); //输出ppz的值,也就是pz的地址(一级指针变量的地址)
Print("*ppz",*ppz); //输出z地址
Print("**ppz",**ppz);//输出z的值
//L、空指针 :void * p;
//类型为void*的指正,比如malloc()返回的就是空指针
//因为它事先不知道要返回何种类型的指针,所以返回void*类型的指针
//然后由用户强制转换为其他类型的指针
//其他类型的指正相互转换时,不能得到正确的数据
char *ch = (char*)functionReturningAddress();
Print("*ch",*ch);
free(ch);
double *db = (double*)functionReturningAddress();
Print("*db",*db);
//void*在c++中不存在
//M、野指针 : 指向非法地址的指针
int *pm = &z; //随便写的一个地址
pm += 100; //改变pm的指,使其指向一个无效的地址,它就变成了一个野指针
Print("pm",pm);
Print("*pm",*pm);
//N、NULL指针 :指向NULL地址的指针
Print("NULL",NULL);//此处输出一个0
// Print("*NULL",*NULL);//error: NULL不是一个指针变量,不能在其前面加*
//C++中是这样定义 NULL 的
/*
#ifndef NULL
#ifdef __cplusplus
#ifndef _WIN64
#define NULL 0
#else
#define NULL 0LL
#endif
#else
#define NULL ((void *)0)
#endif
#endif
*/
return 0;
}