C语言的函数

函数指针

(一)、
1、函数的地址 = &函数名(或者直接可以等于函数名,但较多用的还是&函数名)
2、函数名是指针常量,保存的是函数入口的地址
(二)、例子
int func(int num)
{
    printf("num == %d\n",num);
}
int main()
{
    func(5);
    int (*p_func)(int);  ☆
    printf("%d\n",sizeof(p_func));   △

1、函数名只有一个字节:如果将☆处修改为:int *p_func(int),则还是一个字节,如果将 △    处修改为sizeof(func)
还是一个字节
2、函数指针为四个字节:如果将☆ 处修改为int (*p_func)(int);结果为4,将△ 修改为sizeof(&func)结果为4
3、函数名是什么?是函数的入口地址      
     函数的入口地址是什么?&函数名
    (以上两者并不矛盾,只是两种不同的表述)

函数指针数组

(一)、定义:
int (*p_func_array[3])(int);
(二)、初始化:
假设前面已经定义了三个调用函数func1,func2,func3
p_func_array[0] = &func1;
p_func_array[1] = &func2;
p_func_array[2] = &func3;
(三)、调用:
假设要每个函数要调用30次:
for(i = 0;i < 30;i++)
    for(j = 0;j < 30;j++)
    {
        p_func_array[j](5);
    }

回调函数

void func4(int (*p_func)(int))
{
    p_func(5);
}
int main()
{
    func4(&func1)
    func4(&func2)
    func4(&func3)
}
回调函数的好处是统一接口,增强扩展性

函数

(一)、函数可以不加形参名,比如:void swap_int(int,int);但是最好加上
(二)、函数接口(就是一个函数)的三大要素
1、函数原型
2、函数的说明文档,其中包括函数的功能,函数形参的作用,函数的返回值
六、传值和传参:
例子:
#include <stdio.h>


void exchange(int *p1,int *p2)
{
    int temp;


    temp = *p1;
    *p1 = *p2;
    *p2 = temp;


}


int main()
{
    int num1;
    int num2;


    printf("Please enter num1:");
    scanf("%d",&num1);


    printf("Please enter num2:");
    scanf("%d",&num2);


    exchange(&num1,&num2);


    printf("The result is:num1 == %d,num2 == %d\n",num1,num2);


    return 0;
}


假设用的是传值,则可假设栈空间内存分配如下:


函数的调用过程:
1、通过函数名找到函数的入口地址
2、给函数的形参分配空间
3、传参,将实参传给形参
4、执行函数体结构语句,交换temp,a,b
5、函数返回值返回
6、释放栈空间
7、再打印num1,num2
传值不能进行交换的原因是返回值执行过后,栈空间已经被释放,根本没有进行交换


假设用的传地址


对x,y指向的内存空间进行操作,即对a,b直接进行操作
例子:
void add_ptr(char &ptr)
{
    ptr++;
}
int main()
{
    char *ptr = "hello world";
    add_ptr(ptr);
    printf("%s",ptr);
}


ptr并不是指针本身的地址,而是h的地址,是ptr的内容,要传&ptr,对其地址进行操作,形参需要用指针的指针来接:**ptr


传参总结:
1、只读(想对操作数只使用不修改)实参变量对应空间的值传实参变量名。
2、写(想对操作数使用并且修改)实参变量对应空间的值传实参变量的地址。


另外:
1、char a[] ="hello world";可以修改因为数组分配在栈空间
2、char *a = "hello world";不可修改因为分配在全局变量区的or段


传出参数和传入参数

(一)、
传出参数:output
传入参数:input
(二)、例子:
int continue_max(char *src,char *dest)
{
    return max;
    …………
}
int main()
{
    char *src = "dqihwdcb1234365fsdnr";
    char dest[100];
    continue_max(dest,src);
    return 0;
}
先定义一个空的字符数组dest,在经过函数填充,可带出值,dest为传出参数,src为传入参数


返回值

(一)、为什么要在主函数最后加return 0?
通知系统程序正常结束,不用再做判断


char *func()
{
    char ptr[100] = "hello world";
    return ptr;
}
int main()
{
    char *ptr = func();
    printf("%s\n",ptr);
    return 0;
}
不行,打印之前栈空间已经被释放
可以定义:static char ptr[] = "hello world";
或者:char *ptr = "hello world";

exit函数

1、exit(1):结束整个程序并退出(括号内可以加任意值,都可以退出)
2、要看在哪一步退出?用echo$?(命令行模式下),打印当前程序结束的返回值
如果在exit(1)处结束的,则输出1,如果在exit(2)处结束的,则输出2,以此类推。
3、但是只打印一二完全没有代表性,可以这样:
if(num == 5)
{
    printf("PASSWD ERROR!");
    exit(1);
}
4、为了增加程序的可读性,可以用宏定义:
#define PASSWD_ERROR 2
{
    exit(PASSWD_ERROR);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值