C语言学习笔记(5)

 

1. 数组作为函数参数

函数是我们学习程序设计语言最基本的东西了,我在此不再赘述。只讨论一种特殊情况,就是数组作为函数的参数传递。

我们都知道,其实在传递数组的时候,实际上是传递了数组首元素的指针。明确了这一点之后,我们就可以思考下面的问题。

既然他只是传递了数组首元素的指针,那么他必然无法知道整个数组的大小,因此,我们如果希望在函数中用到数组的长度,必须要进行显式传递。

int Sum(int a[],int size)
{
int i ,sum=0;
for(i=0;i<size;i++)
{
sum+=a[i];
}
return sum;
}

那么既然,函数无法检测传入数组的长度,我们也可以利用这一个特性来计算数组前N个数的和,或者是利用这一特性来告诉函数,实际上,数组的有效长度要小于数组的真实长度。

2. C99中变长数组作为函数参数

首先在数组一节中,我们谈到了C99中的变长数组是个很好的东西。那么我们来看看变长数组作为函数参数的情况。

我们看之前的代码,size和a[]并没有直接的联系,那么当变长数组作为参数就会解决这样的情况。

int Sum(int size,int a[size])
{
int i ,sum=0;
for(i=0;i<size;i++)
{
sum+=a[i];
}
return sum;
}

这个代码,则明确地表示了数组a的长度是size,也就是说在size和a[]之间建立起了直接的联系。

但是在这里我们需要注意一点,就是参数的顺序,长度一定要写在数组之前,否则会出现a[size]找不到size的错误。

在进行函数声明时,我们可以有以下几种方式:

int Sum(int ,int a[*]);
int Sum(int n ,int a[n]);
int Sum(int n, int a[*]);
int Sum(int ,int a[]);
int Sum(int n ,int a[]);

个人比较推荐第一种,因为我觉得第一种最为简便,而且可以表明a是一个变长数组。像第四种和第五种,我个人认为是两种很不好的方式。

3. C99中数组参数声明使用static

C99中允许在数组参数声明中使用关键字static。例如:

int Sum(int a[static 10],int n)
{

}

从函数本身来讲,static并没有对函数的本身实现造成任何影响。static 10的含义是数组的长度至少是10。那么当函数调用时,编译器会事先从内存中取出10个数,而不是在函数调用的时候才一次次的去取,这样就可以使函数的效率更高。

4. main函数的返回值

在初学C语言的时候,谭老的书上大部分都是这样的代码:

void main ()
{
printf("Hello world");
}

但是实际上,这段函数有两个缺陷:

A. 从编程风格上来看,最好显式地声明main函数没有参数

B. main函数应该返回状态码,在某些操作系统中,程序终止时可以检测到状态码,来监视程序是否正常结束。即使你不需要这个状态码,其他人也可能需要。

因此,这个函数最好这样来实现:

int main (void)
{
printf("Hello world");
return 0;
}

还记得我们之前说过exit(0)么,我们之前说,在main函数中写return 0和exit(0)是没有区别的。那么我们就来看看return 和 exit的区别。

exit属于<stdlib.h>头文件,我们之前说过,0是状态码中成功的意思,那么为了更直观,C标准库为我们提供了这样的两个宏定义。

int main (void)
{
printf("Hello world");
exit(EXIT_SUCCESS); //成é功|
exit(EXIT_FAILURE); //失§败ü
}

让我们转向定义可以发现:

/* Definition of the argument values for the exit() function */

#define EXIT_SUCCESS 0
#define EXIT_FAILURE 1

在<stdlib.h>中的这两个宏定义。但是这两个值并不是固定的,而是由实现定义的。

另外,return 和 exit的一个最典型差异就是,在其他函数中调用return 不会引起程序的终止,但是无论在哪里调用exit都会引起程序终止,我们看一个程序。

int main (void)
{
printf("Begin\n");
BreakTest();
printf("End\n");
}

int BreakTest()
{
return 0;
}

这段代码不应该产生任何疑问:

 

接下来看下这段代码:

int main (void)
{
printf("Begin\n");
BreakTest();
printf("End\n");
}

int BreakTest()
{
exit(EXIT_SUCCESS);
}

 

由此可知,exit使整个的程序都被终止了。

 

5.exit与_exit

_exit()函数:直接使进程停止运行,清除其使用的内存空间,并销毁其在内核中的各种数据结构;
exit()函数则在这些基础上作了一些包装,在执行退出之前加了若干道工序。
exit()函数与_exit()函数最大的区别就在于 exit()函数在调用 exit 系统调用之前要检查文件的打开情况,把文件缓冲区中的内容写回文件。

 

posted @ 2011-06-17 00:44  dzqabc  阅读(368)  评论(0编辑  收藏  举报