【每天学点C语言】-4-指针与函数

玩指针,玩指针,玩指针,玩指针,玩指针,玩指针。。。。。。。

然后就被指针玩了

指针型参数

参数传递到函数里作为局部变量,其改变一般并不会影响到原本的数据,因为实际上操作的是原数据的副本,而让指针作为参数传入函数,可以直接操作原数据,代码如下:

#include <stdio.h>
#include "mm.c"
#include "swap.c"

void sw(int,int);
void pswap(int *,int *);

int main() {

    int x=5;
    int y=9;

    printf("\nx=%d,x-location=%p\n",x,&x);
    printf("y=%d,y-location=%p\n",y,&y);

    sw(x,y);//调用函数并传入int型参数

    printf("\nx=%d,x-location=%p\n",x,&x);
    printf("y=%d,y-location=%p\n",y,&y);

    pswap(&x,&y);//调用函数并传入指针

    printf("\nx=%d,x-location=%p\n",x,&x);
    printf("y=%d,y-location=%p\n",y,&y);

    return 0;
}
#include <stdio.h>

void sw(int x,int y){
    int temp;

    temp=x;//属于局部变量,不会改变主函数中的xy
    x=y;
    y=temp;

    printf("\nx=%d,x-location=%p\n",x,&x);
    printf("y=%d,y-location=%p\n",y,&y);
}
#include <stdio.h>

void pswap(int *x, int *y){
    int temp;

    temp=*x;//通过指针互换数据
    *x=*y;
    *y=temp;

    printf("\nx=%d,x-location=%p\n",*x,x);
    printf("y=%d,y-location=%p\n",*y,y);
}

最后打印结果如图:
这里写图片描述

第一种方法虽然在自己的域内互换了x,y的值,但从地址可以看出这里的x、y和之前的数据并不是同一对,而第二种方法通过指针操作了原地址的数据,主函数的x、y也随之而变

由于数组的名字为第一个元素的地址,所以传递参数为数组的时候主函数中的数组会随着方法体中一起改变,但传入的并不是整个数组而是第一个元素的地址,使用sizeof()可以看出,其参数大小一般为4字节


函数指针

指向函数的指针of course

#include <stdio.h>

int add(int,int);
int sub(int,int);
int cal(int (*p)(int,int),int,int);  //int (*p)(int,int)即为函数指针

int main() {
    printf("3+5=%d\n",cal(add,3,5));//函数名即函数地址
    printf("3-5=%d\n",cal(sub,3,5));

    return 0;
}

int cal(int (*p)(int,int),int x,int y){
    return (*p)(x,y);  //p(x,y);也可以,为阅读方便一般使用前面的写法
}

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

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

结果如图:
这里写图片描述


指针函数

返回值为指针的函数,如:

#include <stdio.h>

char *getWords(char);  //返回值为指向char型数据的指针

int main() {
    char input;

    printf("输入字母:");
    scanf("%c",&input);

    printf("%s\n",getWords(input));

    return 0;
}

char *getWords(char c){
    //char str[]="Apple";   //编译器不推荐返回局部变量

    switch (c){
        case 'a':
            //return &str;   //就算返回局部变量的地址,其销毁导致打印没有内容
            return "Apple"; //返回的是'A'的地址,编译器会读到结尾的'\0'为止
        case 'b':
            return "Banana";
        case 'c':
            return "Cat";
        case 'd':
            return "Dog";
        default:
            return "Nope";
    }
}

输入对应字母便可打印出相应的单词,这是通过指针函数的返回值获取到数据地址,从而打印出对应的单词

如果指针指向为函数自身的内部栈空间即为非法,如果数据的生命周期没有函数长,那么返回的地址就会无效


函数指针作为返回值

理想中的格式为:

int (*)(int,int) select(char)

但是编译器会认为这是两个函数而编译报错,正确格式为:

int (* select(char op))(int,int)

其中select(char op)的返回值为指针,地址为add或sub,则此行变为:

int (*fp)(int,int)

返回值为函数指针

下面是例子:

#include <stdio.h>

int add(int,int);
int sub(int,int);
int cal(int (*)(int,int),int,int);
int (* select(char))(int,int);

int main() {
    int num1,num2;
    char op;

    printf("输入式子:");
    scanf("%d%c%d",&num1,&op,&num2);

    int (*fp)(int,int)=select(op); //select函数正确返回了一个函数指针

    printf("%d %c %d = %d\n",num1,op,num2,cal(fp,num1,num2));

    return 0;
}

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

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

int cal(int (*fp)(int,int),int x,int y){
    return (*fp)(x,y);
}

int (* select(char op))(int,int){
    switch (op){
        case '+':
            return add;
        case '-':
            return sub;
    }
}

运行结果如图:
这里写图片描述
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值