C语言:指针(第二天)

C语言:指针(第二天)

变量指针与指针变量

指针变量指向数组

通过指针引用数组元素

引用一个数组元素,可以用:

① 下标法:如a[i]形式。

② 指针法:如*(a+i)或者*(p+i)。其中a是数组名,p是指向数组元素的指针变量,其初值:p = a;

案例

需求:有一整型数数组a,有10个元素。输出数组中的全部元素。

分析:要输出个元素的值,有三种方法。

  • 下标法:通过改变下标输出所有元素

    #include <stdio.h>
    
    void main()
    {
        int arr[10];
        int i;
        // 给数组元素赋值
        for(i = 0;i < 10;i++)
        {
            scanf("%d",&arr[i]);
        }
         // 遍历数组元素
        for(i = 0;i < 10;i++)
        {
                printf("%-4d",arr[i]);
        }
        printf("\n");
    }
    
  • 指针法:通过数组名计算出数组元素的地址,找出数组元素值

    #include <stdio.h>
    
    void main()
    {
        int arr[10];
        int i;
        // 给数组元素赋值
        for(i = 0;i < 10;i++)
        {
            scanf("%d",&arr[i]);
        }
         // 遍历数组元素
        for(i = 0;i < 10;i++)
        {
                printf("%-4d",*(arr+i));
        }
        printf("\n");
    }
    
  • 指针法:用指针变量指向数组元素

    #include <stdio.h>
    
    void main()
    {
        int arr[10];
        int *p,i;
        // 给数组元素赋值
        for(i = 0;i < 10;i++)
        {
            scanf("%d",&arr[i]);
        }
         // 遍历数组元素
        for(p = arr;p < (arr+10);p++)
        {
                printf("%-4d",*p);
        }
        printf("\n");
    }
    

以上3种写法:

  • 第一种写法和第二种写法执行效率相同。系统是将arr[i]转换为*(arr+i)处理的,即先计算出地址,因此比较费时。
  • 第三种写法比第一和第二种方法块,用指针变量直接指向数组元素,不必每次都重新计算地址。(p++)能大大提高执行效率。
  • 用第一种写法比较直观,而用地址或指针变量的方法难以很快判断出当前处理的元素。

使用指针变量指向数组元素时,(上面第三种写法),注意一下三点:

(p--)相当于arr[i--],先*p,再p--

*(++p)相当于arr[++i],先++p,再*

*(--p)相当于arr[--i],先--i,再*

数组名作函数参数

表现形式:

  1. 形参和实参都是数组名

    void fun(int arr[],int len){...}
    void main()
    {
        int arr[] = {11,22,33};
        fun(arr,sizeof(arr)/sizeof(arr[0]));
    }
    
  2. 实参用数组名,形参用指针变量

    void fun(int *p,int len){...}
    void main()
    {
        int arr[] = {11,22,33};
        fun(arr,sizeof(arr)/sizeof(arr[0]));
    }
    
  3. 实参形参都用指针变量

    void fun(int *p,int len){...}
    void main()
    {
        int arr[] = {11,22,33};
        int *p = arr;
        fun(p,sizeof(arr)/sizeof(arr[0]));
    }
    
  4. 实参为指针变量,形参为数组名

    void fun(int arr[],int len){...}
    void main()
    {
        int arr[] = {11,22,33};
        int *p = arr;
        fun(p,sizeof(arr)/sizeof(arr[0]));
    }
    
    案例

    需求:将数组a中n个整数按相反顺序存放(数组中的元素反转)

    在这里插入图片描述

#include <stdio.h>

void inv(int arr[],int len)
{
    // 反转思路:将第0和n-1个进行对调,将第1个和n-2个对调
    
    // 定义循环变量
    int i = 0,temp;
    
    // 遍历数组
    for(;i < len / 2;i++)
    {
        // 交换
        temp = arr[i];
        arr[i] = arr[len-1-i];
        arr[len-1-i] = temp;
    }
}

/**
 * 数组的反转:指针实现
 * const 给变量的数据类型前面添加const,代表这个数据是只读变量
 */
void inv2(int *p,const int len)
{
    // 定义循环变量
    int *i = p,*j = &p[len-1],temp;

    // 遍历数组
    for(;i<j;i++,j--)
    {
      // 反转数组
      temp = *i;// 这里的*是解引用
      *i = *j;
      *j = temp;
    }
}

// 遍历数组
void get(int arr[],int len)
{
    for(int i=0;i<len;i++)
    {
        printf("%-3d",arr[i]);
    }
    printf("\n");
}

int main(int argc,char *argv)
{
    int arr[] = {11,22,33,44,55};

    get(arr,sizeof(arr)/sizeof(arr[0]));
    
    inv2(arr,sizeof(arr)/sizeof(arr[0]));
    
    get(arr,sizeof(arr)/sizeof(arr[0]));
    
    return 0;
}

数组指针与指针数组

数组指针

概念:数组指针是指向数组的指针,本质上还是指针

特点:

  • 先有数组,后有指针

  • 它指向的是一个完整的数组

    • 一维数组指针:

      • 语法:

        数据类型(*指针变量名)[容量];
        
      • 案例:

        /**
         * 数组指针:指向数组的指针(这里不是指向数组元素的指针)
         */
        #include <stdio.h>
        
        int main(int argc,char *argv)
        {
            // 一维数组指针
            // 先有数组,再有指针
            int arr[] = {100,200,300};
            
            // 获取数组的元素个数
            int len = sizeof(arr) / sizeof(arr[0]);
            
            // 定义一个数组指针,指向arr[]这个数组
            // int *p = arr;实际上指向了数组的第一个元素
            int(*p)[3] = &arr;// &arr[0] 等价于 arr;此时p不是指向arr数组的第一个元素,而是指向arr这个数组本身
            printf("%p\n",p);
            
            // p++;此时会跳出整个数组
            // printf("%p\n",p);
            
            // 如何访问数组指针
            printf("%d\n",(*p)[2]);// 此时就拿到了数组中的第三个元素300
            
            // 遍历
            for(int i = 0;i < len;i++)
            {
                printf("%d\n",(*p)[i]);
            }
            printf("\n");
            
            return 0;
        }
        

        我们之前所学的是指向数组元素的指针,本质山还是指针变量;现在学的是指向数组的指针,叫做数组指针。

    • 二维数组指针:

      • 语法:

        数据类型(*指针变量名)[][];
        
      • 案例:

        写法1:

        #include <stdio.h>
        
        int main(int argc,char *argv[])
        {
            // 创建一个普通的二维数组
            int arr[][3] = {10,20,30,100,200,300,1000,2000,3000};
            
            // 创建一个二维数组指针
            // 一个二维数组本质上还是一个一维数组,只不过它的元素也是数组
            int (*p)[3][3] = &arr;
            
            printf("%d\n",(*p)[1][0]);
            
            // 遍历
            for(int i = 0;i < sizeof(arr)/sizeof(arr[0]);i++)
            {
                int len = sizeof(arr[i])/sizeof(int);
                for(int j = 0;j < len;j++)
                {
                    printf("%-4d",(*p)[i][j]);
                }
                printf("\n");
            }
            return 0;
        }
        

        写法2:

        #include <stdio.h>
        int main(int argc, char *argv[])
        {
          // 创建一个普通的二维数组
          int arr[][3] = {10, 20, 30, 100, 200, 300, 1000, 2000, 3000};
          // 创建一个二维数组指针
          // 一个二维数组本质上还是一个一维数组,只不过它的元素也是数组
          int(*p)[3] = arr;        // 取二维数组的第一个元素 {10,20,30} 数组名本身就代表数组首元素(地址)
          printf("%d\n", (*p)[0]); // 10
          // 获取元素2000
        printf("2000-%d,%d,%d",*(*(p+2)+1),*(p[2]+1),p[2][1];// *(*(p+1)+2) 300
        return 0;
        }
        
  • 指针和数组中符号优先级:() > [] > *

  • 通过指针引用多维数组

在这里插入图片描述

案例1

需求:用指向元素的指针变量输出二维数组元素的值

#include <stdio.h>

int main(int argc,char *argc[])
{
    // 定义一个普通的二维数组
    int a[3][4] = {1,3,5,7,9,11,13,15,17,19,21,23};
    
    // 定义一个指针变量,用来接收二维数组的元素值
    int *p = a[0];// a[0][0]
    
    // 循环遍历
    for(;p < a[0]+12;p++);
    {
        // 每4个换行
        if((p-a[0]) % 4 == 0)
        {
            printf("\n");
        }
        printf("%-4d",p);
    }
    printf("\n");
    
    return 0;
}
案例2

需求:数组指针-输出二维数组任一行任一列元素的值

/**
 *
 */

#include <stdio.h>

int main()
{
    // 定义一个二维数组
    int a[3][4] = {1,3,5,7,9,11,13,15,17,19,21,23};
    
    // 创建一个一维的数组指针指向一个二维的数组
    int (*p)[4] = arr;// 等价于&arr[0]
    
    // 创建两个变量,代表我们对应数据的行和列
    int row,col;
    
    // 通过控制台输入
    printf("请输入行号和列号:\n");
    scanf("%d,%d",&row,&col);
    
    printf("arr[%d][%d]=%d\n",row,col,*(*p+row)+col);// *(*p+row)+col | *(p[row]+col) | p[row][col]
    
    return 0;
}

指针数组

概念:指针数组是一个数组,数组中的每一个元素都是一个指针。

特点:

  • 先有指针,后有数组
  • 指针数组的本质是一个数组,只是数组中的元素类型为指针

语法:

数据类型 *数组名[容量]

案例:

#include <stdio.h>

int main()
{
    // 定义三个变量
    int a = 10,b = 20,c = 30;
    
    // 定义指针数组,指针数组是用来存放指针的
    int *arr[3] = {&a,&b,&c};
    
    // 获取元素大小
    int len = sizeof arr / sizeof arr[0];
    
    // 遍历数组
    for(int i = 0;i < len;i++)
    {
        printf("%-3d",*arr[i]);
    }
    printf("\n");
    
    return 0;
}

建议:我们一般使用指针数组处理字符串

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值