指针的分类
- 普通指针
- 数组指针
- 指针数组
- 函数指针
- 指针函数
什么是指针变量?
允许用一个变量来存放指针,这种变量称为指针变量,指针变量的值就是某份数据的地址。
这样的一份数据可以是数组、字符串、函数,也可以是一个普通变量。
格式为:类型 *指针变量名; | 类型 *指针变量名=初值表达式;
普通指针
普通变量的指针&多重指针
// 指向普通变量的指针
int num=10;
int *q = # // 创建了一个整型的指针变量指向num变量的地址
printf("%d %d\n",q,*q); // 输出:6422036 10
// 解释:q存放的是num变量的地址,*q将该地址的值取出来
int **a = &q; // 创建了一个二重指针变量a指向指针变量q的地址
printf("%d %d %d\n",a,*a,**a); // 输出:6422024 6422036 10
// 解释:a存放的是q的地址,*a为q地址里存放的内容,即num的地址,**a即num地址对应的值num
int ***b = &a; // 创建了一个三重指针变量b指向二重指针变量a的地址
printf("%d %d %d %d\n",b,*b,**b,***b); // 输出:6422016 6422024 6422036 10
// 解释:b = a指针变量的地址 *b = q指针变量的地址 **b = num的地址 ***b = num值
字符串变量的指针
// 指向字符数组的指针
char ch[20]="Hello world!";
char *c = ch; // 创建了一个字符变量c指向字符数组的首地址,即指向字符串的首地址
printf("%d %c %s\n",c,*c,c); // 输出:6422016 H Hello world!
// 解释:c = ch的首地址 *c = ch[0](首地址对应的值) 输出%s,从首地址开始遇到'\0'结束
printf("%c %c %c",*c++,*c++,*c++); // 输出:l e H
// 解释:printf参数为从右至左执行。*c++先执行*c,再将c的值+1,即指向ch[1]
一维数组的指针
// 指向一维数组的指针
int nums[10]={1,2,3,4,5,6};
int *n = nums;// 创建了一个整形变量n指向一维数组的首地址nums 或者 &nums[0]
printf("%d %d %d %d %d",n,*n,*(n+1),n[2],*(++n)); // 输出:6422004 2 2 3 1
// 解释:n = nums数组的首地址 *n = nums[0] *(n+1) = nums[1] 也可以直接把n作为数组操作
数组指针
指向整个数组的指针,也称行指针
int nums[3][3]={1,2,3,4,5,6,7,8,9};
int (*n)[3]=nums;// 定义了指向3列数组的指针
printf("%d %d %d\n",n[0][0],n[0][1],n[0][2]); // 输出:1 2 3
n++; // 解释:n原本指向第一行的 1 2 3 ; n++ 之后,指向第二行的 4 5 6 ;
printf("%d %d %d\n",n[0][0],n[0][1],n[0][2]); // 输出:4 5 6
指针数组
定义多个指针变量
int *n[3]; // 定义了三个指针变量分别为n[0]、n[1]、n[2]
int a=2,b=3,c=4;
n[0]=&a; n[1]=&b; n[2]=&c;
printf("&a = %d\n",&a); // 输出:&a = 6422012
printf("%d %d %d %d %d\n",n,*n,**n,*n[1],*n[2]); // 输出:6422016 6422012 2 3 4
// 解释:n表示指针数组的地址,*n表示首地址对应的值-即*n=&a,**n=a
函数指针
指向一个函数的地址
int add(int a,int b){
return a+b;
}
int (*fadd)(int a,int b);// 声明函数指针
int main(){
fadd = add; // 将函数指针fadd 指向 函数add的地址,函数名即地址
int c = fadd(1,2);
printf("%d",c); // 输出3
return 0;
}
指针函数
返回一个指针变量
int *add(int a,int b){
int *c = &a;
a = a + b;
return c;
}
int main(){
int *f = add(1,2);
printf("%d",*f); // 输出 3
return 0;
}
自定义头文件的使用
// 主函数 main.cpp
#include <iostream>
#include "mode1.h"
#include "mode2.h"
using namespace std;
int main(int argc, char** argv) {
int c = add(12,20);
cout<<c<<endl;
int d = mul(2,3);
cout<<d<<endl;
return 0;
}
方式1 :声明定义均写在mode1.h中
// mode1.h
#ifndef _MODE1_H_ //常用#ifndef #define #endif来避免重复编译和包含
#define _MODE1_H_
int add(int x,int y);
int add(int x,int y){
return x+y;
}
#endif
方式2:声明写在mode2.h文件中,定义写在mode2.c文件中
// mode2.h
#ifndef _MODE2_H_
#define _MODE2_H_
// 方式2:声明写在mode2.h文件中 定义写在mode2.c文件中
int mul(int x,int y);
#endif
// mode2.c
#include "mode2.h"
int mul(int x,int y){
return x*y;
}