9 用户自定义函数
9.1 返回多个值的函数
一般我们使用return语句只能返回一个值,假设我们需要从函数中获得更多的信息该怎么办?在C语言中,我们可以使用参数,不仅接收信息,而且还往调用函数返回信息。用于返回信息的参数称为输出参数。
使用地址运算符(&)和间接运算符(*)可以实现。如下:
void mathoperation(int x, int y, int *sum, int *diff);
int main(int argc, char const *argv[])
{
int x = 20, y = 10, s, d;
mathoperation( x, y, &S, &d );
printf("s = %d d = %d \n", s, d );
}
void mathoperation(int x, int y, int *sum, int *diff)
{
*sum = x + y;
*diff = x - y;
}
该函数的第一条语句x和y的值相加,结果保存在sum指向的存储位置。记住,该存储位置就是s的存储位置。因此,保存在由sum指向的存储位置中的值就是s的值。
用指针进行传递的规则:
- 实参和形参的类型必须相同
- 实参(在函数调用中)必须是变量(他是调用函数的局部变量)的地址
- 函数头中的形参必须以间接运算符*为前缀
- 在函数原型中,其参数也必须以*为前缀
- 要在被调用函数中访问实参的值,必须使用相应的以间接运算符*为前缀的形参
- 按值传递:实参的值被复制给被调用函数参数列表中的变量。被调用函数使用的是实参的副本,而不是其原始值。这就确保调用函数的原始值不被随意修改。
- 按指针传递:发送给被调用函数的是变量的地址,而不是值的副本。在这种情况下,被调用函数是直接作用于调用函数的数据,因此,调用函数可以使用已修改的值。如操作数组和字符串时,经常使用;或者需要被调用函数返回多个值时。
在C语言中,变量不仅属于某种数据类型,而且还具有某种存储类型。
- 自动变量是在某个函数中生命的变量,当调用该函数时创建变量,函数推出时自动销毁。自动变量是所在函数的私有(局部)变量,又称局部或内部变量。默认情况下,如果生命在某个函数中的变量没有指定存储类型,则为自动变量。
- 在整个程序中都是存在并且活动的变量称为外部变量,或全局变量。与局部变量不同的是,他可以被程序的所有函数访问。它在函数的外面进行声明。
- 如果局部变量与全局变量同名,那么在声明局部变量的函数中,局部变量具有比全局变量更高的优先级
- 一旦全局变量声明后,任何函数都可以使用和修改其值,这样,后面它的函数就只能引用其新值了
- 只有从全局变量的声明之处开始到程序的末尾可用。
- 全局变量默认的初始化为0
int main(int argc, char const *argv[])
{
extern int y; //外部声明
return 0;
}
func()
{
extern int y;
}
int y; //声明全局变量
func1()
{
y = y + 1;
}
4.
静态变量的值可以一直保持到程序结束。使用static可以将变量声明为静态的。可以分为内部类型和外部类型。
- 在某个函数中生命的为内部静态变量。内部static变量类似于auto,只不过auto变量在程序其余部分仍保持有效
void stat(void);
int main(int argc, char const *argv[])
{
int i;
for ( i = 0; i < 4; ++i)
{
stat();
}
system("pause");
return 0;
}
void stat()
{
static int x = 0;
x++;
printf("x = %d\n", x );
}
- 外部static变量声明在所有函数之外,因此对程序的所有函数都可用。static外部变量与简单外部变量的区别是,staitc外部变量只在定义他的文件中可用,而简单外部变量可以被其他文件访问。
register int count;(大多数编译器只允许把int和char类型的变量保存在寄存器中)
9.3 多文件程序
实际的程序中,一般包含多个源文件,这些文件被分别编译,然后连接成一个可运行的目标代码。只要把变量声明为外部变量,多个源文件就可以共享它。被两个或多个文件共享的变量称为全局变量,因此必须在某个文件中进行相应的声明,然后再其他文件中显示的用extern进行引用。
在test_35.c中main函数可以引用变量m,该变量在test_36.c中声明为全局的。但是,函数func1不能访问变量m。因为extern语句在main函数内部,如果extern语句放在main函数之前,或者在每个函数中都使用了extern语句,那么每个函数都可以访问变量m。
extern说明符告诉编译器,后面的变量类型和名称已经在其他地方进行了声明,不用为他们创建存储空间了。由链接器去解决。注意,多文件全局变量只能是在某一个文件(而且只有一个)中不带extern说明符进行声明。如果在两个不同文件(这两个文件被一个程序使用)中把一个变量声明为全局变量,那么链接器将产生一个冲突,不知道该使用那个变量,因此发出一个警告。
当一个函数定义在某个文件中,被另一个文件访问,那么在第二个文件中必须包含该函数的声明。该声明表明该函数是一个外部函数,其定义出现在其他的地方。我们通常把这种声明放在文件的开始处,位于所有函数之前。尽管所有函数都假定为外部的,但良好的习惯是在函数声明时显示的使用extern。