【C语言必经之路——第11节】初阶指针(2)

五、指针的运算

1、指针与整数相加减

看一下下面的代码:

#include<stdio.h>
int my_strlen(char* str)
{
    int count=0;
    while(*str!='\0')
    {
        count++;
        str++;//指针加减整数
    }
    return count;
}
int main()
{
    int len=my_strlen("abcdef");
    printf("%d\n",len);
    return 0;
}

指针加减整数的时候就要看看这个指针式什么类型的指针,就决定着该指针所跨过的字节数,比如上免得代码,str为char*类型的指针,当运行一次str++时,就会往后走一个字节,str就指向了下一个字符。所以指针与整数相加减就是将指针在“字节”上运动,跨的步子大小就是指针类型所决定啦。

2、指针-指针(地址-地址)

(1)、条件

  • 指针都是指向同一块区间的

  • 指针的类型是一致的

总结一下:指针减指针是指针之间元素的个数

//strlen的模拟实现
#include<stdio.h>
int my_strlen(char* str)
{
    char* start=str;
    while(*str!='\0')
    {
        str++;//指针加减整数
    }
    return str-start;//这里经过两个指针相减,可以得到两个指针所指地址之间的元素个数
}
int main()
{
    int len=my_strlen("abcdef");
    printf("%d\n",len);
    return 0;
}

3、指针的关系运算

下面是一个for循环遍历values数组的一个例子

//方法一
for(vp = &values[N_VALUES]; vp > &values[0];)
{
  *--vp = 0;
}
//改进版本
for(vp = &values[N_VALUES-1]; vp >= &values[0];vp--)
{
  *vp = 0;
}

实际在绝大部分的编译器上是可以顺利完成任务的,然而我们还是应该避免这样写,因为标准并不保证

它可行。

标准规定:

允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针比较,但是不允许与

指向第一个元素之前的那个内存位置的指针进行比较。

六、指针和数组

这里不得不提一下数组名这么一个东西,他呢不只是单单一个名字这么简单,他其实是首元素的地址,换句话说,一个指针如果指向数组首元素,那么几乎可以说这个指针喝这个数组名是等价的。注意,这里说的是几乎,因为数组名在下面两个情况是不能用首地址这么简单的来理解

1. sizeof(数组名),计算整个数组的大小,sizeof内部单独放一个数组名,数组名表示整个数
组。
2. &数组名,取出的是数组的地址。&数组名,数组名表示整个数组。

除去上面两种情况,既然可以把数组名当成地址存放到一个指针中,我们使用指针来访问一个就成为可能。

例子:

#include <stdio.h>
int main()
{
  int arr[] = {1,2,3,4,5,6,7,8,9,0};
  int *p = arr; //指针存放数组首元素的地址
  int sz = sizeof(arr)/sizeof(arr[0]);
  for(i=0; i<sz; i++)
 {
    printf("&arr[%d] = %p  <====> p+%d = %p\n", i, &arr[i], i, p+i);
 }
  return 0;
}

所以 p+i 其实计算的是数组 arr 下标为i的地址。

七、二级指针

​​​​​​​二级​​​​​​​指针是指向一级指针,一级指针的值是变量的地址,二级指针的值是一级指针的地址

#include<stdio.h>
int main()
{
    int a=10;//a在内存空间申请4个字节
    //一级指针
    int* pa=&a;//0x0012ff40,pa是指针变量,用来存放a地址,也得向内存申请4/8字节
    //二级指针
    int** ppa=&pa;//0x0012ff48,ppa是指针变量,用来存放pa地址,也得向内存申请4/8字节
    return 0;
}

八、指针数组

指针数组是存放指针的数组

#include<stdio.h>
int main()
{
    int a=1;
    int b=2;
    int c=3;
    int* arr[]={&a,&b,&c};//arr就是指针数组,分别a,b,c的地址给arr[0],arr[1],arr[2]
    for(int i=0;i<3;i++)
    {
        printf("%d ",*arr[i]);
    }
    return 0;
}

用指针数组模拟二维数组

#include<stdio.h>
int main()
{
    int a[]={1,2,3};
    int b[]={3,4,5};
    int c[]={5,6,7};
    int* arr[]={a,b,c};
    for(int i=0;i<3;i++)
    {
        for(int j=0;j<3;j++)
        {
            printf("%d",arr[i][j]);//模拟二维数组,和二位数组还是有差距
            //printf("%d",*(*(arr+i)+j));
        }
        printf("\n");
    }
    return 0;
}
 

今天的分享就到这啦😉


如果我的文章对您有帮助,

“点赞” “收藏” “关注” 一键三连哦!

想了解更多知识请前往故里♡927的博客

如果以上内容有什么问题,欢迎留言,大家一起学习,共同进步。


我们下期见😉~~

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

故里♡9513

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

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

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

打赏作者

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

抵扣说明:

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

余额充值