指针数组的本质是数组,只是每个数组的元素为指针
32位平台:
char*arr1[4];
int *arr2[4];
short *arr3[4];
sizeof(arr1)==168;
sizeof(arr2)==168;
sizeof(arr3)==168;
8.4.1 数值的指针数组
int *arr[4]; 指针数组
int *arr[4]={&num1,&num2,&num3,&num4};
int num1=10;
int num2=20;
int num3=30;
int num4=40;
//int arr[4]
//int *p;
int *arr[4]={&num1.&num2,&num3,&num4};
int n=sizeof(arr)/sizeof(arr[0]);
int i;
//遍历输出
for(int i=0;i
8.4.2 字符指针数组
char*arr[4]={"hehehehe","xixixixi","lalalala","hahahaha"};
arr[0]存放的是hehehehe的首元素地址,存放在栈区/全局区(看这个数组是全局还是局部),同时,"hehehehe"被存放在文字长量区。注意:文字长量区的值不可被修改
char*arr[4]={"hehehehe","xixixixi","lalalala","hahahaha"};
int n=sizeof(arr)/sizeof(arr[0]);
int i;
for(i=0;i
8.4.3 二维字符数组
char*arr1[4]={"hehehehe","xixixixi","lalalala","hahahaha"};
char arr2[4][128]={"hehehehe","xixixixi","lalalala","hahahaha"};
arr1是在指针数组 存放的是每个字符串的首元素地址
arr2是二维数组 存放的是每个字符串
8.5 指针的指针
int num=10;
int *p=#
int **q=&p;
如果想要保存p的地址,则需要两个*号
n级变量可以保存n-1级指针变量的地址
8.6数组指针
int arr[5]={10,20,30,40,50};
int (*p)[5];//数组指针,注意()不能去掉,去掉就和5结合
#include
using namespace std;
void test1() {
int arr[5] = { 10,20,30,40,50 };
int(*p)[5] = &arr;//数组指针
cout << "sizeof(p)=" << sizeof(p) << endl;
cout << "p=" << p << endl;
cout << "p+1=" << p + 1;
}
int main() {
test1();
return 0;
}
int arr[5]={10,20,30,40,50};
int(*P)[5]=&arr; //数组指针
*p==*&arr==arr;*和&抵消
对数组首地址取*==数组首元素地址
注意:若想取arr[2]内容,必须*(*p+2)=*(*(p+0)+2)==*(p[0]+2)==p[0][2]
8.6.2二维数组和数组指针的关系
int arr[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};
arr[0] (值为1,2,3,4) |
arr[1] (5,6,7,8) |
arr[2] (9,10,11,12) |
arr[1]=>*(arr+1) //第1行第0列的列地址
&arr[1]=>arr+1 //第1行的行地址
*arr+1=>//第0行第1列的列地址
arr[1]+2=>*(arr+1)+2=>//第1行第2列的列地址
#include
using namespace std;
int main() {
int arr[3][4] = { {1,2,3,4},{5,6,7,8},{9,10,11,12} };
int row = sizeof(arr) / sizeof(arr[0]); //行为3
int col = sizeof(arr[0]) / sizeof(arr[0][0]);//列为4
int* p = &arr[0][0];
int i = 0;
for (int i = 0; i < row * col; i++) { //依次输出arr[i]
cout << p[i] << " ";
}
return 0;
}
8.8 指针与函数
8.8.1 指针变量作为函数的参数
如果想在函数内部 修改外部变量的值 需要将外部变量的地址 传递给函数(重要)
案列1 单向传递之值传递
函数内部 不能修改外部变量的值
#include
using namespace std;
void setNum01(int data)
{
data=100;
}
void test1(){
int num=0;
setNum01(num);//单向传递之 传值
cout<<"num="<
案例2 单向传递之传地址
函数内部就可以修改外部变量的值
void setNum02(int *p)//int *p=#
{
*p=100;
}
void test2(){
int num=0;
setNum02(&num);//单向传递之传地址
cout<<"num="<
8.8.2 一维数组作为函数的参数
函数内部想操作(读或写)外部数组元素,将数组名传递给函数
注意:一维数组 作为函数的形参 会被优化成指针变(面试中常用)
//void outIntArray(int arr[5], int n) {
// 注意:一维数组作为函数的参数 会被编译器 优化成 指针变量
void outIntArray(int *arr, int n) {
cout << "内部sizeof(arr)=" << sizeof(arr) << endl;
for (int i = 0; i < n; i++) {
cout << arr[i] << " ";
}
}
void test02() {
int arr[5] = {10,20,30,40,50};
int n = sizeof(arr) / sizeof(arr[0]);
cout << "外部sizeof(arr)=" << sizeof(arr) << endl; //20B
//遍历数组:
outIntArray(arr,n);// 10 20 30 40 50
}
int main() {
test02();
return 0;
}
8.8.3 二维数组作为函数的参数
函数内部 想操作 函数外部的二维数组 需要将二维数组名 传递给函数
二维数组 作为函数的形参 会被优化成 一维数组
//void outputIntArray(int arr[3][4], int row, int col) {
//二维数组作为函数的形参 会被优化成 一维数组指针
void outputIntArray(int ( * arr)[4],int row,int col){
cout << "内部sizeof(arr)=" << sizeof(arr) << endl;
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
cout << arr[i][j] << " ";
}
cout << endl;
}
}
void test03() {
int arr[3][4] = { 1,2,3,4,5,6,7,8,9,10,11,12 };
int row = sizeof(arr) / sizeof(arr[0]);
int col = sizeof(arr[0]) / sizeof(arr[0][0]);
cout << "外部sizeof(arr)=" << sizeof(arr) << endl;
//遍历数组
outputIntArray(arr, row, col);
}
int main() {
test03();
return 0;
}
8.8.4 函数的返回值类型为 指针类型
将函数内部的合法地址 通过返回值 返回给函数外部
int* getAddr(void) { int data = 20; //data在函数内部,是局部变量,在函数被调用之后会被释放 //*p就等于在访问一个被释放的空间,这时候就会出现段错,操作非法空间 return &data; //不要返回普通局部变量的地址 } void test04() { int* p = NULL; p = getAddr(); cout << "p=" << *p;//结果会出现段错,输出不了 } int main() { test04(); return 0; }
修改之后为:
int* getAddr(void) {
//int data = 20;
//data在函数内部,是局部变量,在函数被调用之后会被释放
//*p就等于在访问一个被释放的空间,这时候就会出现段错,操作非法空间
static int data = 20;
//添加局部静态变量static
return &data; //不要返回普通局部变量的地址
}
void test04() {
int* p = NULL;
p = getAddr();
cout << "p=" << *p;//20
}
int main() {
test04();
return 0;
}
8.9 函数指针
函数名 代表函数的入口地址:
函数指针:本质是一个指针变量 只是改变量 保存的是函数的入口地址
int myAdd(int x, int y) {
return x + y;
}
void test05() {
int(*p)(int x, int y) = NULL;
//函数指针和函数入口地址建立关系
p = myAdd;
//通过p调用myAdd函数(函数+(实参))
cout << p(10, 20); //30
}
int main() {
test05();
return 0;
}
8.9.2 函数指针变量注意:
函数指针变量不要+1 无意义
不要对函数指针变量取*
8.9.3 函数指针变量 使用typedef定义
int myAdd(int x, int y) {
return x + y;
}
void test05() {
typedef int(*FUN_abs)(int x, int y);
FUN_abs p = NULL;
//函数指针和函数入口地址建立关系
p = myAdd;
//通过p调用myAdd函数(函数+(实参))
cout << p(10, 20); //30
}
int main() {
test05();
return 0;
}
8.9.4 函数指针作为函数的参数
目的:让算法功能多样化
案例1:设计一个算法,完成加减乘除
int myAdd(int x, int y) {
return x + y;
}
int mysub(int x, int y) {
return x - y;
}
int mymul(int x, int y) {
return x * y;
}
int mydiv(int x, int y) {
return x / y;
}
int choice(int x, int y, int (*func)(int, int)) {
return func(x, y);
}
void test07() {
cout << choice(20, 30, myAdd) << endl;
cout << choice(20, 30, mysub) << endl;
cout << choice(20, 30, mymul) << endl;
cout << choice(20, 30, mydiv) << endl;
}
int main() {
test07();
return 0;
}