目录
1.常用指针(基础)
2.指针数组
3.指向指针的指针
4.指向一维数组的指针
5.结构体指针、文件指针
6.指向函数的指针
一、常用指针(基础)
指针的使用
1.指向对象 (=,&)
对象分为:存储区的首地址或者其他指针。
2.代表存储区(数据区 *)
用法: * 指针名 或 * 首地址
指针的概念
1.指向数据区的首地址
从物理上说也就是内存上存储数据的位置。
2.指针变量
作用:用于存储数据去的首地址。
(1)建立指针变量:
int * p ; /*P为int类型的指针变量,可指向整型的存储区*/
char * p1 , * p2 ; /*指向字符型的存储区*/
(2)指针变量存储首地址
int a , *p ; /*a为整型数据,用于存储整型数据*/
p = &a ;
建立指针变量图
指针的主要操作
1.指向数据区的首地址(=,&)
int * p , *p1 ; /*存放首地址*/
int a ; /*存放整数*/
float b ; /*存放浮点数*/
a = 100 ;
b = 3.14 ;
p = &a ; /*指针p现在指向a的首地址*/
p1 = &b ; /*指针p1现在指向b的首地址*/
/*
float型数据所占大小:sizeof(float)=4字节
但 指向float型数据的指针p1所占的内存大小为:sizeof(p)=2字节
因为p1存储的是b的首地址编码,对p1内存大小无影响。
*/
知识拓展:
代码:p = 100 ;
也可以执行,但输出值不一定是100。
指针指向变量首地址的物理示意图
建立数组:
int a[5] = { 1,2,3,4,5} , *p = a;
内存示意图
拓展:
a[0]的表示有:
(1)a :数组首地址指针;
(2)*a :代表常量a[0];
(3)&a[0] :a[0]的指针;
(4)*(&a[0]):代表常量a[0];
* 首地址 :代表首地址所指向区域的一切。
那么,如何利用指针来使用变量呢?
首先设置int a =200 , *p ;
p = &a ; /*指向变量a的存储区*/
用指针使用变量对照表
变量a | *p | |
变量名 | a = 200 | *p = 200 |
存储区(内存) | a = 200 | *p = 200 |
数值 | int y = a + 5 ; 则 y = 205 | 同样也可以y = *p + 5 ,y的值同样为205 |
输出:
printf ( " %u " , p) ;
printf ( " %u " , &a) ;
printf ( " %p " , p) ;
字符型变量乃至浮点型变量的用法也一样
指针的运算
设int a [10] , *p ;
p = a ;
指针 +或- n(整数):得到新的地址
示例:p + 1 :得到a[1]的首地址
拓展:指针的数据类型决定+或- 整数n后新地址的位置。
int 型指针一个位移量为一个int区域:
如:p + 1 :为a[1]的首地址。
但如果是 char型指针,一个位移量为一个char(1B)区域:
示例如下:
int *p1 , ch ;
p1 = & ch ;
p1 + 1 : 移到下一个字节的首地址
指针的移动
指针移动可代表每个元素的首地址,也可以改变指针变量的值。
int a [10] , *p ;
p = a ; /*p指向数组a的首地址*/
p = p + 1 ; /*也可以表示为p = a + 1 ; 都是指向变量a[1]的地址*/
p ++ ; /*效果等同于p + 1*/
p -- ; /*效果等同于p - 1*/
fot( p = a ; p < a + 10 ; p ++ )
scanf( " %d ", p) ; /*通过指针p 的移动依次给数组a里的变量赋值*/
指针的大小比较
按其首地址值的大小比较,也就是地址编号的值。
只有同类型的比较,同意连续区域的指针比较大小才有意义。
指针相减
相同类型的指针相减才有意义。
表示两者之间相差的数据块(有指针类型决定)的个数。
如:int a[10] , *p ; p = &a[ 8 ] ;
p - a:相差2B大小的8个数据块。
p-a数据块示意图
指针对字符串的访问
示例:找一段字符串中的最大值。
char st [80] , *p , *max;
p = st ; /*指向st[0]的地址*/
gets ( p ) ; /*输入: good evening ! 回车*/
max = st ; /*指向st[0]的地址*/
for( ;* p != '\0' ; p++)
if( *p > *max ) max = p ;/*继承更大值的地址,p继续循环寻找对比*/
putchar( * max ) ; /*输出最大值*/
示意图如下
指针作为函数的参数
示例:写一个函数对m个整数升序排序。
void sort( int *a , int n )
{
int *p , *p1 , *k , t ;
for( p = a ; p < a + n - 1 ; p++ )
{
k = p ;
for( p1 = p + 1 ; p1 < a + n ; p1++ )
if( *p1 < *k ) k = p1 ;
if( p != k ) { t = *k ; *k =*p ; *p = t ; }
}
return 0 ;
}
二、指针数组(一组常用指针)
建一个数组,所有数组都是指针的数组。
建立指针数组
(1)格式: 数据类型 * 数组名 [常量][···] ;
如:int * ( a [5] ); 或 int *a[5];
拓展:
[ ] 优先级:1
* 优先级:2
int *a[5] :一个名为a的含个指针元素的数组;
int (*a)[5]:一个名为*a的有5个元素的数组;
int (*a)( ):一个名为*a的函数;
指针数组的存储
数组为顺序存储,占同类型字节大小固定不变。
放在都是固定的编号,所以无论指向地址数据大小如何。
数组存储示意图
指针数组的使用
让元素指向数据区。
(1)指向单个数据包
示例:
char *st[5] ;
char a[5] ;
for(int i =0 ; i < 5 ; i++ )
st[i] = a + i ;
for(int i =0 ; i < 5 ; i++ )
scanf("%c" , st[i] );
(2)指向一批数据包
int *a[3] ;
int m[5] , n[10] , c[8] ;
a[0] = m ;
a[1] = n ;
a[2] = c ;
for(int i =0 ; i < 10 ; i++ )
scanf("%d",&(a[1]) [i] );
(3)动态申请存储包
char *st[5] ;
for(int i = 0 ; i < 5 ; i++ )
st[i] = (char *) malloc (80) ;
for(int i = 0 ; i < 5 ; i++ )
gets( st[i] ) ;
for(int i = 0 ; i < 5 ; i++ )
puts( st[i]) ; /*字符串输出,该函数可自动换行*/
for( int i = 0 ; i < 5 ; i++ )
{
for( int j =0 ; )
}