美文网首页程序员
从 0 开始学习 C 语言:使用函数的注意事项

从 0 开始学习 C 语言:使用函数的注意事项

作者: 登龙zZ | 来源:发表于2018-06-06 15:57 被阅读0次

版权声明:本文为 cdeveloper 原创文章,可以随意转载,但必须在明确位置注明出处!

这次与大家分享一些我对 C 语言中函数的简单理解,希望能帮助有疑惑的同学更好的使用这个强大的语言特性。大家在高中的时候都求过数学函数的表达式,其实编程语言的函数与数学表达式实际上是一样的,我们都可以将其理解为一个有输入输出的「功能黑箱」,看下图:

function

就类似给函数一个 x 值,可以求结果一样,给函数一些输入参数,也可以得到相同的输出结果。

模块化编程

为什么要使用函数呢?其实是为了更好的维护软件的功能以及实现模块化编程,你可以想下如果把所有的功能都写在 main 函数中,那该多么可怕,估计没人会读你写的代码。

通过使用函数可以使我们的软件逻辑性更强,单独的功能写在单独的函数中,还可以方便后期复用等等,好处还有很多实在列举不完。其中比较重要的作用要说:模块化编程代码复用了,建议你去找实际的项目看看代码组成,自然就理解了。

函数的副本机制

很多初学者都搞不清楚函数的副本机制,例如下面的交换函数:

#include <stdio.h>

void swap(int a, int b) {
    printf("Address a = 0x%X, Address b = 0x%X\n", &a, &b);
    int x = a;
    a = b;
    b = a;
}

int main(void) {
    int m = 1;
    int n = 2;
    printf("Address m = 0x%X, Address n = 0x%X\n", &m, &n);
    printf("Before: m = %d, n = %d\n", m, n);
    swap(m, n);
    printf("  Swap: m = %d, n = %d\n", m, n);
    getchar();
    return 0;
}

这个函数是错误的,因为函数在进行参数传递的时候,会将传入参数 m,n 的值拷贝给函数的形式参数 a,b,因此在函数内部交换的是形式参数 a,b 的值,而不是交换传递时 m,n 变量的值。

函数的副本机制从内存的角度来说就是:在函数进行参数传递的时候,实参和形参的内存地址是不同的。这是这个例子的输出结果,每个人的机器可能都不同:

Address m = 0x2BFB34, Address n = 0x2BFB28
Before: m = 1, n = 2
Address a = 0x2BFA50, Address b = 0x2BFA54
  Swap: m = 1, n = 2

可以看到变量 m 和 a,以及 n 和 b 的内存地址均不同,因此对值的交换也是不起作用的。但是使用指针就完全不同了,看下面这个例子:

#include <stdio.h>

void swap(int *pa, int *pb) {
    printf("Address pa = 0x%X, Address pb = 0x%X\n", &pa, &pb);
    printf("Address *pa(&m) = 0x%X, Address *pb(&n) = 0x%X\n", pa, pb);
    int x = *pa;
    *pa = *pb;
    *pb = x;
}

int main(void) {
    int m = 1;
    int n = 2;
    printf("Address m = 0x%X, Address n = 0x%X\n", &m, &n);
    printf("Before: m = %d, n = %d\n", m, n);
    swap(&m, &n);
    printf("  Swap: m = %d, n = %d\n", m, n);
    getchar();
    return 0;
}

这个函数才是正确的交换函数,为什么呢?因为我们这里传递的是 m,n 的内存地址,即传递的是指针,所以在函数内部对指针解除引用就可以直接访问这个地址的内容了,这是指针提供的特性。

那么是否就意为着传递指针就没有副本机制了呢?这也是错误的,指针也是变量,本质上与 int 没有区别,只是特性不同罢了。

上面例子在传递指针的时候,也是将 m,n 的地址拷贝给 pa,和 pb,也是存在副本机制的,只不过这里拷贝的是地址而不是值,在内部通过指针的解引用操作可以直接访问 m,n 的内存地址,进而进行交换。

因为指针非常重要,所以建议你自己运行这个程序,可以看到输出结果中 pa 指向的是 m 的内存地址,而 &pa 是指针变量 pa 的内存地址,这两个千万不要搞混了。

一定时时刻刻记住下面的结论:

  1. 一个 int 变量有自己的内存地址,也有自己存储的整数值
  2. 一个指针变量有自己的内存地址,也有自己存储的指向地址值
  3. 变量在内存中都有自己的地址和其存储的内容

函数的参数传递顺序

VC 和 gcc 编译器计算函数参数的顺序都是从右向左,这个特点一点要记住,面试可能会问到。你可以使用下面这个程序去验证,程序比较简单,留作给你的思考(不去思考就等于浪费时间看 cd 这篇文章了):

#include <stdio.h>

void foo(int a, int b) {
    printf("a = %d\n", a);
    printf("b = %d", b);
}

int main(void) {
    int n = 1;
    foo(n, n++);
    getchar();
    return 0;
}

今天就分享一点函数的注意事项,下次见了,Bye

相关文章

  • 从 0 开始学习 C 语言:使用函数的注意事项

    版权声明:本文为 cdeveloper 原创文章,可以随意转载,但必须在明确位置注明出处! 这次与大家分享一些我对...

  • C语言程序可以没有main函数

    学习C语言的同学都知道,每个C程序要有一个main函数,程序从main函数开始执行,在main函数中结束。但事实上...

  • python、main函数和argv参数

    笔者学习和使用过的语言中:C语言,C++语言,C#语言,Java语言都时有main函数在的,main是程序执行的起...

  • C语言中三种输入函数的区别

    在C语言中,有三种主要的输入函数:scanf(),fgets()以及gets()。他们的使用方法及注意事项...

  • VC 在调用main函数之前的操作

    在C/C++语言中规定,程序是从main函数开始,也就是C/C++语言中以main函数作为程序的入口,但是操作系统...

  • 2.头文件与类的声明

    C语言和C++语言中 函数与数据使用方法的不同 C语言中由于C语言中没有某些关键字,所以数据可以被全部函数所使用 ...

  • C语言中函数的使用

    C语言中用函数写ATM 1、目的: 学习掌握函数的使用,任何使思维逻辑清晰化。 2、相关技术,及其使用: 定义函数...

  • iOS 进制转换

    1、使用C语言函数 2、使用输出

  • [转载]C语言函数调用栈

    原文地址:C语言函数调用栈(一)C语言函数调用栈(二) 0 引言 程序的执行过程可看作连续的函数调用。当一个函数执...

  • 函数变参的使用

    介绍C/C++,java,和go语言对函数变参的使用。 1. C/C++语言的变参 1.1 变参函数声明 变参函数...

网友评论

    本文标题:从 0 开始学习 C 语言:使用函数的注意事项

    本文链接:https://www.haomeiwen.com/subject/algbsftx.html