1.理解指针的概念;
2.掌握指针变量的定义与引用方法;
3.掌握指针与数组,字符串之间的联系;
4.掌握函数指针的用法;
1.理解指针的概念
#什么是内存地址?
计算机给变量分配储存空间(容量),即内存单元。字节存储单元指的是能存放一个字节的数据,每个存储单元都有编号,就是存储地址.
#什么是指针和指针变量?
指针就是地址。指针变量就是专门用于存储其他变量地址的变量。
一个指针变量的值就是被指向变量的值。定义指针变量的目的就是通过地址去访问变量的值。
2.掌握指针变量的定义与引用方法;
#指针变量如何定义?
Int *p;//*与p之间可有空格;
Int*p1,*p2;//(yes)
Int*p1,p2;//(no)此时p2不是指针变量;
#指针变量如何赋值?
Int a;//必须先定义
Int*p=&a;//&取地址符
注意:1.若a为数组,不加&的时候表示a[0]的地址赋值给指针变量p,其他需要加上&或者通过指针运算才可以访问
2.未经赋值的指针不可以使用
#什么是零指针?
Int *p = 0;
通常用于避免指针的非法引用。while(p!=NULL){}
#指针变量如何引用?
Int a;
Int *p=&a;//p指向a;此处的*是说明类型的作用
*p=10;//相当于a=10;此处的*时运算符
注意:(*p)++与a++等价;*p++相当于*(p++)
#指针变量与所指向变量的类型?
原则上两者的类型要相同,如int a; int *p;两者都是int 类型
非要不同类型的赋值的话可以使用强制类型转换
3.1.指针与数组
#两者关系?
数组的指针其实就是数组在内存中的起始地址,也就是a[0]的地址。
如:int a[3]={1,2,3};
Int*p=a;//注意此处没有用到&,此时就是指针变量指向a[0]的地址
3.2.指向多维数组的指针——数组指针
#如何用指针p访问n行m列的二维数组a[n][m]?
- *(p+i*n+j);
2. p[i*n+j];
3. *(a[0]+i*n+j);
#如何利用行指针变量来访问多维数组?
以下是四种通过指针引用二维数组的方式:
*(a[i]+j)<==>*(*(a+i)+j)<==>a[i][j]<==>(*(a+i))[j], 表示i行j列的值;
下面是数组指针的定义以及引用:
Int (*p)[4]; //数据类型符(*行指针变量名)[常量表达式]
//定义了含有4个整型元素的一维数组的指针p
p = a;或者p = &a[0]; //初始化指针p
P[i][j];或者*(p[i]+j);或者*(*(p+i)+j);或者(*(p+i))[j]; //通过行指针p引用二维数组a;
通俗的说就是先指定列数 Int (*p)[4];里面的4就是二维数组a的每行的个数,注意不能用变量来指定;
以下是示例代码:
# include <stdio. h>
int main()
{
short int a[2][3]={{1,2, 3},{4,5,6}};
short int (*p)[3];
short int i, j;
p=8; // p指向二维数组 a的第0行行地址
for(i=0;i<2;i++) //变量;控制行数
{
for(j=0;j<3;j++) //变量j控制列数
printf("a[%d][%d]=%d ",i,j, p[i][j]); //显示每个数组元素的值
printf("\n"); //数组的每一行元素输出后换行
}
p++; //p指向二维数组a的第1行行地址
for(j=0;j<3;j++)
printf("%d ", p[0][i]); //显示数组中第1行的元素值
return 0;
}
运行结果:
a[0][0]=1 a[0][1]=2 a[0][2]=3
a[1][0]=4 a[1][1]=5 a[1][2]-6
4 5 6
注意:对行指针赋值,可以是p = a+1;也可以是p = &a[1];
但是不可以用数组列地址对其赋值,如p = a[0];或p &a[0][0];
3.3.元素为指针的数组——指针数组
#代码:
用指针数组对键盘输入的5个整数进行从小到大排序。
int i,j, t;
int a, b, c、d, e;
int*p[5]={&a,&b, &c, &d, &e); //将a,b,c,d,e的内存地址分别赋给p[0],p[1],-,p[4]
scanf("%d,%d,%d,%d,%d", p[0],p[1],p[2],p[3],p[4]); //对 a,b,c,d,e 赋值
for(i=0;i<4;i++)
for(j=i+1;j<5;j++)
if( *p[i]> * p[j]) //交换 p[i]、p[j]所指向的变量值
{
t=*p[i];
*p[i]=*p[j];
*p[j]=t;}
for(i=0;i<5;i++) //显示排序后的结果
printf("%d ", *p[i]);
运行结果(假设输人为:3,8,7,6,4)
3 4 6 7 8
3.4字符串与指针
#啥关系?
字符串的本质是以’\0’,即数字0结尾的字符型数组,第一个字符的地址就是字符串的指针,可以定义一个字符指针变量指向一个字符串。
代码如下:
char *pstr;
pstr=”i love you”;//pstr存储着首字符i的地址
#字符串的引用?
1.逐个字符引用,代码如下:
char * pstr="I Love you!";
for(; *pstr!=!∖0′;pstr++)
printf("%c", * pstr);
运行结果:
I Love you!
- 整体引用,代码如下:
char * pstr="I Love you!";
printf("%s", pstr);
运行结果:
I Love you!
注意:其他类型数组不能整体输出,只能逐个输出。
对比字符数组输出字符串:
char str[] = "Hello, world!"; // 定义一个字符数组
printf("%s", str); // 输出字符数组中的字符串
#什么是野指针?
如果一个指针没有指向一个有效内存就被引用,则称为野指针操作或者空指针赋值。
#字符指针变量的应用?
利用字符指针实现字符串的倒序排列。
# include < string. h>
char str[200], ch;
char *p, - q;
gets(str): //读取一个字符串
p=str; //p 指向字符串的首地址
q=p+strlen(p)-1; //q指向字符串的末地址
while(p<q)
{ //交换 p和 q各自指向的字符
ch=*p;
//将 p所指向的字符保存在 ch中
*p++=*q; //先将q指向的字符赋给p指向的字符单元,p再增1.
*q--=ch;
//先将 ch的值赋给q指向的字符单元,q再减1
}
printf("%s\ŋ", str);
运行结果(假设输入为: I Love you! ✔):
!uoy evoL I
#二级指针处理字符串?
直接看代码:
#include < stdio. h>
# define NULL 0
int main()
char ** p;
char *name[]={"hello", "good", "world", "bye", ""};
p=name+1;
printf("%x: %s ", *p, *p);
p+=2;
while(** p !=NULL)
printf("%s\n", * p++);
return 0;
}
运行结果:
42003C: good bye
4.指针与函数
看代码:
void swapl(int a, int b)
{
int t;
t=a;
a=b;
b=t;
}
void swap2(int * a, int * b)
{
int t;
t= *a;
*a= *b;
*b=t;
}
int main()
{
int a=2, b=4;
swapl(a, b);
printf("a=%d, b=%d", a, b);
swap2(&a, &b);
printf("a=%d, b=%d", a, b);
return 0;
//执行后 a的值仍是2,b的值仍是4
//输出 a=2. b=4
//执行后 a的值是4,b的值是2
//输出a=4, b=2
}
注意:被调函数不能改变实参指针变量的值,但可以改变实参指针变量所指向的变量的值。