C语言中的函数

  为了实现某些功能,我们可以自己编写函数,到用的时候打个函数名上去就能直接使用,这样能减少重复性操作,减少代码量,也有利于程序的模块化。

定义函数

函数的格式:

函数类型 函数名称(形式参数1,形式参数2...)
{
    函数的执行体
}
  • 函数类型:根据函数的返回值来判断。比如,如果函数最终会产生并返回一个整型数,那函数类型就是int;如果只是输出打印一些东西,没有返回值,那函数类型就是void
  • 函数名称:自定,最好能体现函数能实现什么功能
  • 形式参数:可有可无,具体看定义的函数有什么功能。参数要声明类型

例1:定义一个能打印“Hello World!”的函数

#include <stdio.h>
void PrintHelloWorld(void)
{
    printf("Hello World!\n");
}
int main(void)
{
    PrintHelloWorld();
    return 0;
}

例2:定义一个函数,返回某个整型数+1后的值

#include <stdio.h>
int AddOne(int x)//小括号里面的是形式参数
{
    x = x + 1;
    return x;
}
int main(void)
{
    int x = 100;
    x = AddOne(x);
    printf("+1后的值是:%d",x);
}

  例二中,AddOne函数小括号里面的是形式参数,这里的x仅限在AddOne函数里面使用,而且它和main()函数里面的x在内存中的地址不同,因此两个x不会冲突。
  函数中的return则是用于终止函数,并向主调函数返回一个值。return可有可无,具体看定义的函数要实现什么功能

补充

  1. 自定义函数一般都要写在main()函数前面

    #include <stdio.h>
    函数类型 函数名称(参数1,参数2...)
    {
        函数体
    }
    int main(void)
    {
        ...
        return 0;
    }
    

    不过有些编译器会做优化,自定义函数写在main函数后面也可以。如果编译器没做这方面的优化,也可以先在main函数前声明一下自定的函数,然后再在main函数后面写编写这个函数:

    #include <stdio.h>
    函数类型 函数名称(参数1,参数2...);//注意这里有个分号
    int main(void)
    {
        ...
        return 0;
    }
    函数类型 函数名称(参数1,参数2...)
    {
        函数体
    }
    
  2. 在自定义函数中的形式参数,在未出现函数调用时,它们并不占内存中的存储单元。在发生函数调用时,函数中的形式参数会被临时分配内存单元。当函数调用结束后,形参单元会被释放。

  3. 当形式参数名称和main()里的某个变量名称一样时:

    #include <stdio.h>
    void func(int a)
    {
        a = a + 100;
        printf("这里是func函数:a=%d\n",a);
    }
    int main(void)
    {
        int a = 100;
        func(a);
        printf("这里是main函数:a=%d\n",a);
        return 0;
    }
    

    输出结果:

    这里是func函数:a=200
    这里是main函数:a=100
    

      可以看出,尽管func()中的形式参数名称也是a,但是在func()中对形式参数a的操作并不影响main()里面的变量a

      事实上,传进func()中的只是main()里面的变量a数值,而不是地址。main()里面的变量afunc()中的形式参数a,两者在内存中的地址并不同,因此对其中一个的操作并不会影响到另一个的值。

      下面看第4点,以数组为例说明如果向自定义函数传入地址会怎么样

  4. 如果形式参数设为数组,则在调用改函数时传进去的只是这个数组的首地址,因此说形式参数不存在数组的概念:

    #include <stdio.h>
    void func(int Array[])
    {
        printf("%d\n",sizeof(Array));
    }
    int main(void)
    {
        int data[] = {1,2,3,4,5};
        printf("%d\n",sizeof(data));//输出结果是20
        func(data);//输出结果是8
    	return 0;
    }
    

      在上方例子中,自定义函数时尽管设了个数组作为形式参数,但实际上这个参数并非真正的数组,而只是数组的首地址。func()中其实执行的是“sizeof(data数组的首地址)”,输出结果是8(因为操作系统中是用8个字节来表示一个地址)。

      而正是因为在调用func()时,传进func()里去的是数组的首地址,因此func()对数组的操作其实就是对main()里面的data数组进行操作:

    #include <stdio.h>
    void func(int Array[])
    {
        Array[3] = 8;
    	puts("这里是func函数,data数组是:");
    	for(int i=0;i<5;i++)
    		printf("%d  ",Array[i]);
    	printf("\n");
    }
    
    int main(void)
    {
        int data[] = {1,2,3,4,5};
        func(data);
    	puts("这里是main函数,data数组是:");
    	for(int i=0;i<5;i++)
    		printf("%d  ",data[i]);
    	return 0;
    }
    

    输出结果:

    这里是func函数,data数组是:
    1  2  3  8  5
    这里是main函数,data数组是:
    1  2  3  8  5
    

    可以看到,func()是真的会直接影响到main()中的数组data。与补充第3点不同,第3点中传入自定义函数的只是变量的数值(而不是变量的地址)。

  5. 如果参数是二维数组要注意正确写法:第二个中括号里面不能省略数字。例:int arr[2][3]int arr[][3]

  6. 如果使用函数递归(递归例子见下面的例二),一定要避免陷入死循环

  7. 函数返回值的类型其实也是函数的类型,如果返回值类型和函数类型不同,则以函数类型为准:

    int f(void)
    {
        return 10.5;
    }
    

    因为函数f()类型是int,所以当f()被调用后,最终返回的值是10,而不是10.5。因此返回值要注意类型,如果类型不同,可能会发生强制转换从而影响结果,或出现编译警告。

  8. 只要函数中的return语句被执行,则return所在的函数就会被终止

  9. 一个程序有且只能有一个主函数main()

  10. 一个函数的功能应该尽量独立,单一

  11. 函数也可以分类为库函数和自定义函数,平时所用的printf()就是库函数。对库函数的声明是通过#include <stdio.h>来实现的

    std是standard(标准),i是input(输入),o是output(输出),h是header(头文件)

  12. 函数是C语言的基本单位,类是Java,C#,C++的基本单位

小例子

例一:定义一个打印整形数组的函数

#include <stdio.h>
void PrintArray(int ArrayName[],int ArraySize)
{
    for(int i=0; i<ArraySize; i++)
    {
        printf("%d  ",ArrayName[i]);
    }
    printf("\n");
}

int main(void)
{
    int data[] = {1,2,3,4,5};
    int length = sizeof(data)/sizeof(data[0]);
    PrintArray(data,length);
}

例二:有一个数列:10,12,14,16,18,20…,输入第几项(n),输出第n项的数值

#include <stdio.h>
int getVal(int n)
{
    if(n==1)
        return 10;
    else
    {
        n--;
        return getVal(n)+2;
    }
}

int main()
{
    int num;
    puts("请输入第几项(n):");
    scanf("%d",&num);
    printf("第%d项是:%d",num,getVal(num));
    return 0;
}

例三:求n!

#include <stdio.h>
int FactorialOf(int n)
{
	if(n==1 || n==0)
		return 1;
	else
		return n * FactorialOf(n-1);
}
int main(void)
{
	int num;
	puts("请输入要求的阶乘数:");
	scanf("%d",&num);
	printf("%d的阶乘结果是:%d\n",num,FactorialOf(num));
	return 0;
}

在32位的计算机中,本例最多只能求16的阶乘,求17的阶乘结果就会不准确,因为int类型最大值只有2147483647(231-1)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值