学C绝对不能错过的入门指南——指针篇

目录

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 ; )

}

 

······未完待续,请看下期内容······

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

腰痛也要站着说话

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值