C语言学习之函数

函数用于将一个大任务分割成若干个较小任务,最常见的就是main函数,main函数是整个程序的入口。

关于main函数的写法,C标准定义了两种写法:

如果不带参数可以这样写

int main(void) { /* ... */ }

如果带参数一般这样写

int main(int argc, char *argv[]) { /* ... */ }

argc表示参数的个数,argv为参数列表。

一个设计的恰当的函数应该屏蔽具体设计细节,只留出相应接口,这样也便于维护。


1. 按值传递

一个函数包括参数列表和一个返回值,但是在操作函数时请注意,函数参数都是按值传递的。

void swap(int a, int b)

{

    int temp = b;

    b = a;

    a = temp;

}


int main(void)

{

    int a = 3;

    int b = 2;

    swap(a, b);

    return 0;

}

上面的程序有什么问题吗?

你会发现a和b的值根本就没有被交换。因为在main函数中调用swap函数时,只是将a、b的值3和2传递给了swap函数,swap函数中只是使用了这两个值而已,所以说自然不能交换main函数中的a、b值。

解决这个问题可以使用一个办法,即传递a、b的地址给swap函数。

void swap(int* a, int* b)

{

    int temp = *b;

    *b = *a;

    *a = temp;

}


int main(void)

{

    int a = 3;

    int b = 2;

    swap(&a, &b);

    return 0;

}

传递指针并没有违反值传递这个规则,这里只是传递了a、b两个变量的地址给swap函数,swap函数可以使用这两个地址间接访问main函数中的a、b变量,自然而然可以交换它们的值。


2. 函数返回值问题

函数的返回值也是值传递的,但是需要注意的是:函数的返回值不能是其中栈上变量的地址,因为在函数调用完成后,函数中的栈上变量随之被销毁,你如果继续使用这个地址,将会导致非法访问。

char* get_message()

{

    char msg[] = "Aren't pointers funs?";

    return msg;

}


int main(void)

{

    char* string = get_message();

    puts(string);

    return 0;

}

上面的程序有什么问题吗?上面的程序就是犯了返回栈上变量的地址问题,我们对这种问题称为野指针,因为它指向了非法区域。


3. 函数递归

所谓函数递归,就是一个函数可以直接或间接的调用自己。

int factorial(int n)

{

    if (n == 1) {

        return 1;

    } else {

        return n * factorial(n - 1);

    }

}

当然也可以用其它方法来实现这个函数。

int factorial(int n)

{

    int j = 1;

    int i = 1; 

    while (i <= n) { 

        j *= i;

        i++; 

    }

    return j;

}


posted @ 2012-05-01 00:26  移动应用开发  阅读(243)  评论(0编辑  收藏  举报