C语言关于指针的那些事

        c语言中对初学者来说让人比较头疼的就是指针了,这次对常用的指针做一个总结,希望可以帮助新手对指针有更好的理解。

一、一级指针和二级指针

1.一级指针

int a=10;
int *p=&a;
char *q="hello";//此为指针的定义
a=*p=20;//指针的使用
char *q="hello";
p++;q++;//指针的操作

2.二级指针

int a=10;
int *p=&a;
int **q=&p;//q是二级指针
//a<==>*p<==>**q
//&a<==>p<==>*q
//&p<==>q

二、指针和数组

1.指针和一维数组

int s[5]={1,2,3,4,5};
int *p=s;
//s[i]<==>*(s+i)<==>p[i]<==>*(p+i)

需要注意的是这四个用法虽然可以等价,但是有不同的涵义,p代表的是指针变量,而p是字符串常量,不能被修改,为巩固练习,请做以下判断。

char *p="hello world";
char a[]="hello world"


p++          //正确,指针是变量可以进行操作。
*p++         //正确,取出值后指针指向下一位。
(*p)++       //错误,取出的值是字符串常量,不能修改。
*p='M'       //错误,取出的值不允许被修改。
p="hqyj"     //正确,指针可以改变,指向另一个字符串。
a++          //错误,a是数组名,是常量。
*a++         //错误,a是数组名,是常量。
*a='M'       //正确,等价于a[0]。
a="hqyj"     //错误,a是数组名,是常量。

2.数组指针

        本质是一个指针,指向二维数组,也叫做行指针。

int s[3][4];
int (*p)[4]=s;//4表示列。
//s[i][j]<==>*(s[i]+j)<==>*(*(s+i)+j)
//<==>p[i][j]<==>*(p[i]+j)<==>*(*(p+i)+j)

3.指针数组

        本质是一个数组,数组中每一个元素都是指针。

char *s[4];
//定义了一个s指针数组,其中有4个元素
s[0]="hello";
s[1]="beijing";
char value='M';
s[2]=&value;

三、指针与函数

1.指针函数

        本质是一个函数,返回值是一个地址。

        如char *strcpy(char *dest, const char *src);

不能返回可以返回
局部变量的地址static修饰的局部变量地址
malloc函数在堆分配的空间地址
全局变量的地址
#include <stdio.h>
#if 0
//错误的 不能返回局部变量的地址
int *function1(int x, int y){
    int temp = x+y;
    return &temp;
}
#endif

int *function2(int x, int y){
    static int temp = 0;
    temp = x+y;
    return &temp;//可以返回static修饰的局部变量的地址
}

int ret = 0;
int *function3(int x, int y){
    ret = x+y;
    return &ret;//可以返回全局变量的地址
}

int main(int argc, const char *argv[]){
    int *p = NULL;
    //p = function1(10, 20);
    //printf("%d\n", *p);

    p = function2(10, 20);
    printf("%d\n", *p);//30

    p = function3(10, 20);
    printf("%d\n", *p);//30

    return 0;
}

2.函数指针

        本质上是一个指针,指向一个函数

格式:

        返回值类型(*函数指针名)(函数的形参表)

多用于将函数作为函数的参数传递。

#include <stdio.h>
#if 0
//错误的 不能返回局部变量的地址
int *function1(int x, int y){
    int temp = x+y;
    return &temp;
}
#endif

int *function2(int x, int y){
    static int temp = 0;
    temp = x+y;
    return &temp;//可以返回static修饰的局部变量的地址
}

int ret = 0;
int *function3(int x, int y){
    ret = x+y;
    return &ret;//可以返回全局变量的地址
}

int main(int argc, const char *argv[]){
    int *p = NULL;
    //p = function1(10, 20);
    //printf("%d\n", *p);

    p = function2(10, 20);
    printf("%d\n", *p);//30

    p = function3(10, 20);
    printf("%d\n", *p);//30

    return 0;
}

函数指针经常被用于回调函数

#include <stdio.h>

int my_add(int x, int y){
    return x+y;
}

int my_sub(int x, int y){
    return x-y;
}

//将函数指针作为函数的形参,在函数内部通过函数指针p调用函数时
//具体调的是哪一个函数 取决于用户调用jisuan函数时传的第三个参数,
//第三个参数传的是哪个函数 通过p调用的就是哪个函数
//相当于通过p回头去调用用户指定的函数----称之为回调函数
int jisuan(int x, int y, int (*p)(int, int)){
    return p(x, y);
}

int main(int argc, const char *argv[]){
    int a = 10;
    int b = 20;
    printf("%d\n", jisuan(a, b, my_add));//30
    printf("%d\n", jisuan(a, b, my_sub));//-10

    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值