目录
指针
- 内存编址:每个字节都有唯一的编号 (地址)
- 地址为无符号整数,16进制
- 指针不是地址,指针变量的值是一个地址
- 可以保存变量、数组、字符串的首地址,保存函数的入口
定义
- 基类型 *变量;
- 基类型:指针变量指向的数据类型
- %p:输出变量地址
- 指针变量使用前必须初始化
- 不知道指向那里,就指向NULL
- 初始化:
- 基类型 *变量1=&变量2
- 基类型 *变量1;变量1=&变量2
#include <stdio.h>
#include <stdlib.h>
int main()
{
int a=1;
//int *pa;//定义指针
int *pa=&a;//指针初始化;
//int *pa=NULL;//指针初始化
//pa=NULL;//指针初始化
printf("%d\n", a);
printf("&a=%p\n",&a);
printf("pa=%p\n",pa);
}
空指针
- 值为NULL的指针
指针解引用
- 通过间接寻址运算符访问指针指针指向变量的值
- 在指针变量说明中,“”是类型说明符,表示其后的变量是指针类型,而表达式中出现的“”则是一个运算符用以表示指针变量所指的变量。
- 基类型 *变量=&变量1;
- *变量=变量2;
- 说明:*变量为变量1的别名,可以赋值
#include <stdio.h>
#include <stdlib.h>
int main()
{
int a=0;
int *pa=&a;//指针初始化;
*pa=1;//给a赋值
printf("a=%d\n", a);
printf("*p=%d\n",*pa);//等价上一条语句
return 0;
}
指针变量作为函数参数
- 可以通过实参变量的地址,进而改变指针形参的值
- 这样函数可以返回多个值。
- 提供了修改实参值得方法
#include <stdio.h>
void Fun(int *par);//函数指针
int main()
{
int a=1;
printf("a=%d\n" ,a);
Fun(&a);//传递地址
printf("a=%d\n",a);
return 0;
}
void Fun(int *par)
{
printf("a=%d\n",*par);
*par=2;
}
案例
#include <stdio.h>
void Swap(int *x,int *y);
int main()
{
int a=5,b=9;
Swap(&a,&b);
printf("a=%d,b=%d",a,b);
return 0;
}
void Swap(int *x,int *y)//两数交换
{
int temp;
temp=*x;
*x=*y;
*y=temp;
}
函数指针
- 格式:数据类型 (*指针变量名)(形参列表);
- 作用
- 编写 通用性更强的函数
- 实例1:通用计算任意函数定积分得函数
- 实例2:通用的排序函数
- 方便直接在主函数调用其他函数
int Max(int x,int y);
int (*f)(int,int);//声明了函数名为f,返回值是整型指针类型得函数;在main里面
f=Max;//Max是定义得函数名
result=(*f)(a,b);//调用赋值
案例
#include <stdio.h>
void Fun(int x,int y,int (*f)(int,int));
int Max(int x,int y);
int Min(int x,int y);
int Add(int x,int y);
int main()
{
int a,b,result;
int (*f)(int,int);
printf("请输入:\n");
scanf("%d,%d",&a,&b);
Fun(a,b,Max);
Fun(a,b,Min);
Fun(a,b,Add);
return 0;
}
void Fun(int x,int y,int (*f)(int,int))//直接输出
{
int result;
result=(*f)(x,y);
printf("%d\n",result );
}
int Max(int x,int y)//判断最大数
{
printf("max=");
return x>y?x:y;
}
int Min(int x,int y)//判断最小数
{
printf("min=");
return x<y?x:y;
}
int Add(int x,int y)//计算总和
{
printf("sum=");
return x+y;
}
指向指针的指针
-
如果一个指针变量存放的又是另一个指针变量的地址,则称这个变量为指向指针的指针变量或指向指针的指针。
-
定义方式: 数据类型 **变量名;
-
在指针变量说明中,“”是类型说明符,表示其后的变量是指针类型,而表达式中出现的“”则是一个运算符用以表示指针变量所指的变量。
int a=10; //地址为&a
int *p=&a; //指针地址为&p 如果是p就是a的地址
int **p1=&p; //指针地址为&p1 如果是*p1就是&p</span>
#include<stdio.h>
#include<stdlib.h>
int main()
{
const char *s[]={"man","woman","girl","boy","sister"};
const char **q;//定义指向指针的指针变量
int k;
for(k=0;k<5;k++)
{
q=&s[k]; /*在这里填入内容*/
printf("%s\n",*q);//*p指的对应地址的内容
}
return 0;
}
指针和数组
- 可以用指针代替数组下标操作
算数运算
- 加上整数,减去整数,两个指针相减
- 参与运算:加,减整数,自增,自减,关系,赋值
指针指向数组元素才有意义
- p+j不是加j个字节,而是取决于p的基类型
- 指向同一数组时,还可以比较
#include <stdio.h>
int main()
{
int a[10];
int *p,*q;
p=&a[i];
q=p+j;
q=p-j;
}
指针与一维数组
首地址&a[0]
- &a[i]等价于(a+i)
- a+1指的是:a+i*sizeof(基类型)
- 数组地址的相差取决于基类型
#include <stdio.h>
int main()
{
int a[5],*p=NULL;
for(p=a;p<a+5;p++)
{
scanf("%d",p);
}
for(p=a;p<a+5;p++)
{
printf("%4d\n",*p);
}
}
自加区别
-
*p++是指下一个地址。
-
(*p)++是指将星p所指的数据的值加一。
//*p++与(*p)++区别
#include <stdio.h>
int main()
{
int x,y,a[]={1,2,3,4,5},*p=a,*q=a;
printf("%d\n",*p );
x=*p++;//执行这一句后x=a[0]=1,p=a+1
printf("%d\n",x);
y=(*q)++;//执行这一句后,y=a[0]+1=2,q仍然=a
printf("%d\n",y );
}
指针与二维数组
指向二维数组的行指针
定义
- int (*p)[3];//行指针,基类型int[3]类型
- int *q[3];//指针数组
int a[2][3];
//a[i][j]的元素值等价于*(*(p+i)+j)
//*(p+i),即a[i],指向第i行第0列的int型元素
//*(p+i)+j指向第j行第j列的int型元素
//*(*(p+i)+j)取出第i行第j列的内容,即a[i][j]
实例
- 按行查找,再按列查找
#include <stdio.h>
int main()
{
int i,j;
int a[2][3]={1,2,3,4,5,6};
int (*p)[3];//行指针,基类型int[3]类型
p=a;//&a[0]指向第0行的int[3]型元素
for(i=0;i<2;i++)//行下标变化
{
for(j=0;j<3;j++)//列下标变化
{
printf("%d\n",*(*(p+i)+j));
}
}
}
指向二维数组的列指针
定义
- int *p;//列指针,基类型是int 型
- 将二维看成一维数组
int *p;
p=&a[0][0];//*(a+0)+0)即&a[0][0],指向a[0][0]的int元素
*(p+i*3+j)//代表着第一个元素,i代表前i行,j代表着本行第j个元素
实例
#include <stdio.h>
int main()
{
int i,j;
int a[2][3]={1,2,3,4,5,6};
int *p;
p=&a[0][0];//*(a+0)+0)即&a[0][0],指向a[0][0]的int元素
for(i=0;i<2;i++)
{
for(j=0;j<3;j++)
{
printf("%d\n",*(p+i*3+j));
}
}
}
指针数组
二维字符数组
- 第二维下标不能省略
- 相对字符指针数组空间浪费
- 定义:char country[][10]={“A”,“E”,“A”,“C”,“j”};
#include <stdio.h>
int main()
{
int i;
char country[][10]={"America","England","Australia","China","a"};//定义二维字符数组
for(i=0;i<5;i++)
{
printf("%s\n",country[i]);//访问数组,输出每行的内容
}
}
字符指针数组
- 每个数组元素都是一个指向字符串的指针
- 定义:char *country[]={“A”,“E”,“A”,“C”,“j”};
#include <stdio.h>
int main()
{
int i;
char *country[]={"America","England","Australia","China","jsf"};
for(i=0;i<5;i++)
{
printf("%s\n",country[i]);//输出每行的内容
}
}
类型
- 用数组指针的基类型-----指向数组的指针
int (*p)[5];
- 用指针作数组的基类型------指针数组
- 元素维指针类型的数组
- 定义:数据类型 *数组名[数组长度]
char *p[5];