1. 指针的定义:指针就是其值为内存地址的变量。一个变量可以直接存放一个特定的数值,而一个指针存放的值则是另外一个有值变量的地址值。变量名是直接引用变量值的,而指针则是间接引用变量值。通过指针引用一个值被称为间接寻址。
指针必须定义后才能使用!
//初始化
int * NumberPtr
读法为:NumberPtr是一个指针,指向int
取地址运算符&是一个一元运算符,该运算返回的结果是操作数的地址值。例如
int y = 5;
int *yPtr;
yPtr = &y;
yPtr =&y的含义是将变量y的地址赋给指针变量yPtr。于是变量yPtr被称为"指向"了y
一元运算符*通常被称为间接寻址运算符 或者解引用运算符,该运算符返回的结果是它的操作数(一个指针)指向对象的值
y的值等于5
初始化
/*初始化*/
void initpo() {
int y = 5;
int *yPtr;
yPtr = &y;
cout << *yPtr << endl;
}
&和*指针运算符
/* &和*指针运算符*/
void poperator() {
int a; //a是一个整型
int *aPtr; //aPtr 是int类型的指针
a = 7;
aPtr = &a; //aPtr设为a的地址
printf("地址为:%p\n 数值为:%p\n", &a, aPtr);
printf("数值为:%d \n *aPtr数值为:%d\n", a, *aPtr);
printf("展示运算符 &*aPtr = %p\n &aPtr = %p", &*aPtr, *&aPtr);
}
2.指针数组
数组元素可以是指针。
2.1 通常用来构造一个字符串的数组(array of string)也简称为字符串数组。
2.2 数组的每个元素都指向一个字符串,但是在C语言中一个植复仇实质上就是一个指向其第一个字符的指针。所以字符串数组的每个数据项实际上就是一个指向字符串第一个字符的指针。
const char * suit [4] = {"Hearts","Diamonds","Clubs","Spades"};
定义中suit[4]这部分表示它是一个有4个元素的数组,声明中的char* 这部分则表示数组suit的每个元素都是"指向字符的指针"类型。限定符const表示由每个指针元素所指向的字符串不允许被改写
suit大小是固定的,也能用它访问任意长度的字符串
图片来自:《C How to Program 第五版》
3.函数指针
函数指针是一个函数在内存中的地址。
函数名起始也就是执行这个函数任务的程序代码在内存中的起始地址。指向函数的指针既可以作为函数实参传递给函数,也可以作为函数返回值从函数返回,还可以将其存在数组中赋值给其他指针。
/************************************************************************/
/* 函数指针! */
/************************************************************************/
void bubble(int work[], const int asize, int(*funptr)(int a, int b)); //实现功能
int ascending(int a, int b);//正
int decending(int a, int b);//倒
void swap(int * dataone, int* datatwo);//交换
void FandPfun() {
int order = 0;
int arrdata[INDEX] = { 2, 6, 4, 1, 10, 5, 9, 123, 21, 23 };
printf("按一正序:");
printf("按二正序:");
cin >> order;
for (int i = 0; i < INDEX; i++)
{
cout << arrdata[i] << " ";
}
if (order == 1)
{
bubble(arrdata, INDEX, ascending);
cout << "正序" << endl;
}
else
{
bubble(arrdata, INDEX, decending);
cout << "倒序" << endl;
}
for (int i = 0; i < INDEX; i++)
{
cout << arrdata[i] <<" ";
}
}
void bubble(int work[], const int asize, int(*funptr)(int a, int b))
{
int count = 0;
for (int i = 0; i < INDEX; i++)
{
for (int j = 0; j < INDEX - 1; j++)
{
if ((*funptr)(work[j],work[j+1]))
{
swap(&work[j],&work[j+1]);
}
}
}
}
int ascending(int a, int b)
{
return b < a;
}
int decending(int a, int b)
{
return b > a;
}
void swap(int * dataone, int* datatwo) {
int temp = *dataone;
*dataone = *datatwo;
*datatwo = temp;
}
讲解↓
int(*funptr)(int a, int b)
如果去掉括号就是
int *funptr (int a, int b)
它声明了一个函数,这个函数的实参是两个整型数,函数的返回值是一个指向整型数的指针。
在这里也可以写成
int (*)(int a, int b)
在bubble中
if ((*funptr)(work[j],work[j+1]))
通过一个指向变量的指针去访问其所指向的变量的值一样,也可以通过一个指向函数的指针去调用它所指向的函数。
也可以不用指针解引用来调用该函数格式如下:
第一种方法是通过指针来调用函数,因为它是显示地说明了funptr是一个指向函数的指针,对函数的调用是通过对函数指针解引用实现的
第二种通过指针调用函数的方法使得funptr看上去更像一个真正的函数