1.9 指针
一、指针的定义与使用
1.什么是地址?
程序运行中的每一个变量都分配有一块内存空间,对应的内存的起始编号称为这个变量的地址。
2.数据访问的两种方式
- 直接访问:程序通过变量名来访问这块空间中的数据的访问方式。
- 间接访问:通过指针变量来访问它所存的变量的方式。
- 指针变量:保存另一个变量地址的变量。
3.指针变量的定义格式
一级指针的定义:数据类型 *变量名;
二级指针的定义:数据类型 **变量名;
三级指针的定义:数据类型 ***变量名;
程序举例:一级指针的简单应用
int main()
{
int num1 = 3;
int *pointer = &num1; //定义整型变量的指针,并初始化指针变量的地址为num1的地址
cout << "num1=" << num1 << "\tnum1:address=" << &num1 << endl;
cout << "pinter=" << pointer << "\tpoint:address=" << &pointer
cout<< " *pointer=" << *pointer << endl;
system(“pause”);
return 0;
}
二、指针变量的基本操作
1.指针变量初始化与赋值的语法格式
数据类型 *指针类型 = 另一个变量初始地址的表达式
2.指针变量赋值
指针变量名 = 地址表达式
3.其他运算
取值运算:*
算术运算:+n , -n
相减运算:p1 - p2
比较运算:p1 < p2
4.程序举例
#include<iostream>
#include<iomanip>
using namespace std;
void output(int *arr, int n);
int main()
{
int intArray[] = { 1, 2, 3, 4, 5 };
int n = sizeof(intArray) / sizeof(intArray[0]);
output(intArray, n);//数组名作函数的参数
int *pPointer = intArray;
int i = 0;
while (pPointer<intArray + n)//指针的+n运算
{
*pPointer = i * 2 + 1;
pPointer++;//指针的++运算
i++;
}
pPointer = intArray;
output(pPointer, n);//指针作函数的能数
system("pause");
return 0;
}
//倒序输出数组元素值
void output(int *arr, int n)
{
int *p;
p = arr + n - 1;//指向数组元素的指针
for (; p >= arr; p--)//指针--运算
cout << setw(3) << *p;
cout << endl;
}
三、动态内存分配
1.运行程序的内存空间分为5个区
全局数据区(data area)
代码区(code arae)
栈区(stack area)
堆区(heap area)
字符常量区
2.程序运行过程中,才能确定数据大小时,这个时候需要根据问题的规模动态分配!
3.动态地址分配内存:new 运算符
- 指针变量名 = new 类型名(初值列表);
- 指针变量名 = new 类型名 [下标表达式];(数组)
- 指针变量名 = new 类型名 [下标表达式1] [下标表达式2] […];
4.内存释放:delete 运算符
- delete 指针变量名;
- delete []指针变量名;(数组)
5.程序举例
int *NewArray(int n); //动态申请一维数组的内存空间
void output(int *arr, int n); //显示数组元素的值
int main()
{
int n;
cout << "输入动态数组的长度:" << endl;
cin >> n;
int *array = NewArray(n);
for (int i = 0; i<n; i++)
{
array[i] = i;
}
output(array, n);
delete[]array;
system("pause");
return 0;
}
//动态申请一维数组的内存空间
int *NewArray(int n)
{
int *p;
p = new int[n];
return p;
}
//显示数组元素的值
void output(int *arr, int n)
{
int *pointerArr = arr;
for (; pointerArr<arr + n; pointerArr++)
{
cout << " " << *pointerArr;
}
cout << endl;
}
四、指针与函数
1.指针做函数的参数
- 指针做函数的参数是一种地址传递方式。
- 指针可以作为函数的形参,也可以作为函数的实参。
- 实参和形参指针变量指向同一内存地址,实现参数双向传递。(不是指针做形参的函数都是单向传递!)
2.指针函数:指针类型的函数
-
函数声明其返回值为指针类型时,这个函数就称为指针函数。
-
主要目的:在函数结束调用结束时,把大量的数据从被调用函数返回到主函数。
-
指针函数的定义
数据类型 *函数名 (参数表)
{
函数体
}
3.函数指针:用来存储函数的入口地址的指针变量
-
函数指针定义格式
返回类型 (*函数指针名)(形参表);
-
函数指针的赋值
函数指针名 = 函数名
-
调用函数指针指向的函数
函数指针名 (实参表);
4.程序举例
#include<iostream>
#include<string>
using namespace std;
#define FUN_MAX 0
#define FUN_MIN 1
#define SIZE sizeof(map)/sizeof(fun_map)
string menu[] = { "计算两数的最大值,输入0","计算两数的最小值,输入1" };
int max(int x, int y);
int min(int x, int y);
void dispMenu(string menu[], int n);
struct fun_map
{
int msg;
int(*pfn)(int, int); //定义指向函数的指针作结构体的成员
};
int main()
{
int a, b, m;
int sel;
//定义fun_map类型的数组并初始化
fun_map map[] = { FUN_MAX, &max, FUN_MIN, &min };
//map[0].msg=0;map[0].pfn=&max;
//map[1].msg=1;map[1].pfn=&min;
int lenMenu = sizeof(menu) / sizeof(menu[0]);
for (int i = 0; i<SIZE; i++)
{
cout << "输入a,b的值:" << endl;
cin >> a >> b;
dispMenu(menu, lenMenu);
cin >> sel;
if (sel == map[i].msg)
m = map[i].pfn(a, b);
cout << "m=" << m << endl;
}
system(“pause”);
return 0;
}
int max(int x, int y)
{
return (x>y ? x : y);
}
int min(int x, int y)
{
return (x<y ? x : y);
}
void dispMenu(string menu[], int n)
{
for (int i = 0; i < n; i++)
cout << menu[i] << endl;
cout << endl;
}
五、指针数组
1.定义:数组元素为指针的数组
2.一维指针数组的定义形式
数据类型 *数组名 [数组元素的个数];
3.使用方式
作为函数的参数
用于指向若干字符串