C语言指针理解及细节

目录

概念

指针类型

相同点

不同点 

指针关系运算

条件

二级指针

指针与数组

指针名和取地址指针名

 用指针访问数组

指针数组 

数组指针

函数指针

函数指针数组 


概念

1.内存中最小单元(一个字节)的编号,也就是地址。即:编号——地址——指针

*我们平常口语所说的指针其实是指针变量,即用来存放指针(地址)的变量

指针类型

相同点

不同类型的指针所占用空间大小是一样的

 由此我们可以做一些强制类型转换

不同点

1.解引用时访问权限不同

 a的初始地址和值:

 int*指针将其修改为0:

char*指针将值修改为0

 

可以看出,指针类型决定了其解引用时的访问权限

2.给指针+1时地址不同

 

 b+n=b+sizeof(int)*n

c+n=c+sizeof(char)*n

*指针类型决定了其走一步的距离

指针关系运算

条件

1.类型一致

2.指向同一块空间

二级指针

概念:存放指针变量地址的指针

a的地址存放在ap中,ap的指针存放在app中,ap是一级指针,app是二级指针

指针与数组

指针名和取地址指针名

对数组arr执行以下三种操作

1:printf("%p",arr);

2:printf("%p",&arr);

3: printf("%p",&arr[0]);

他们的值都是arr的首元素arr[0]的地址

数组名在绝大多数情况下都表示首元素地址,但是有俩种情况除外:

1:sizeof(数组名);此时数组名表示整个数组,计算得到数组的总大小

2:&数组名;这里数组名表示整个数组,从地址角度来说和首元素地址的值一样,但是意义不一样:

 对于&arr,因为它表示这个数组,所以对它加一,它跨过这个数组的大小即4*5=20;

 用指针访问数组

int arr[5]={0};
for(int i=0;i<5;i++)
{
    printf("%d",*(arr+i));
}
for(int j=0;j<5;j++)
{
    printf("%d",arr[j]);
}

俩种方式本质上差不多:

1:取得首元素地址

2:给地址加i

3: arr+i进行解引用,取得对应的值,即arr[i]=*(arr+i)

由此,我们可以推理出

arr[i]=i[arr]=*(arr+i)

指针数组 

概念:存放指针的数组

由此,我们可以得到一种二维数组的表达方式

ptr[i][j]=*(*(ptr+i)+j)

数组指针

数组指针本质上还是一个指针,和int*,char*一样,数组指针是一个指向数组的指针

int a[5]={0};
int (*p)[5]=&a;

 应用:二维数组的首元素是其第一行,所以二维数组的数组名就表示其第一行的地址,这时就需要用到数组指针

函数指针

1.函数的地址就是它的函数名

2.函数名和&函数名意义一样都是函数地址

3.形式:返回类型 (*指针名)(参数类型)=函数名;

int add(int x,int y)
{

}
int (*p)(int ,int)=add;//add为一个函数名
//调用
int a=p(3,5);//*号可以省略

函数指针数组 

存放函数指针的数组 - 函数指针数组

形式:返回类型 (*指针名[元素数量])(参数类型)={数组中存放的函数名};

函数指针数组的调用

形式:返回类型 接收返回值变量名=指针名[调用函数在数组中的位置](参数)

应用举例:简单计算器

#include <stdio.h>
int add(int a, int b)
{
 return a + b;
}
int sub(int a, int b)
{
 return a - b;
}
int mul(int a, int b)
{
 return a*b;
}
int div(int a, int b)
{
 return a / b;
}
int main()
{  
    int x, y;
     int input = 1;
     int ret = 0;
     int(*p[5])(int x, int y) = { 0, add, sub, mul, div }; //转移表
     while (input)
     {
          printf( "*************************\n" );
          printf( " 1:add           2:sub \n" );
          printf( " 3:mul           4:div \n" );
          printf( "*************************\n" );
          printf( "请选择:" );
      scanf( "%d", &input);
          if ((input <= 4 && input >= 1))
         {
          printf( "输入操作数:" );
              scanf( "%d %d", &x, &y);
              ret = (*p[input])(x, y);
         }
          else
               printf( "输入有误\n" );
          printf( "ret = %d\n", ret);
     }
      return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值