1、函数简介:
- 为了实现某种需求的特定的功能
2、声明一个函数
- 函数必须要有声明,否则是无法使用的。声明格式如下:
#include <stdio.h>
void fun9(); //声明一个函数
void main() {
fun9();//调用
getchar();
}
//实现方法体
void fun9() {
printf("helloworld");
}
如果没有声明就直接编写方法体的话,是无法通过编译的,如果实在不想声明的话,那么方法体必须定义在main函数之前,这样就能通过编译。
3、函数返回值说明
- 将一个方法执行的结果返回给调用者。这里需要说的是当方法的返回值返回的是该方法内的一个局部变量时,该局部变量必须由static修饰,否则可能会造成数据失效。例如
#include <stdio.h>
int* fun9();
void main() {
int *ptr = fun9();
printf("ptr=>%d",*ptr);
getchar();
}
int* fun9() {
int n = 100;
return &n;
}
- 在上面的代码中,fun9()方法将其局部变量n的地址返回了,我们知道,当fun9()将地址返回,那么fun9()在栈中开辟的内存就会立即销毁,所以,局部变量也随之失效,但是,原本n所占据的那块内存并不会清0,而是任然保存n的值,通俗点说,就像租门面一样,你只有居住权,但没有它的所有权,如果哪天有个人愿意出更高的钱租这个门面,那么,你就得走人,所以,当系统需要为其他数据分配内存的时候,如果分配到的刚好是保留n的数据的那一块,那么这时候,“它就得走人”,也就是会将这里面的数据覆盖掉,我们先来看上面代码的输出结果
可以看到,这时候n的数据还没有被覆盖掉,这就是我们上面说的,只有居住权,而且是随时都会被取代的那种,接下来,我们来模拟一波土豪,有钱任性,你这个地方我出10倍的价钱租了:
#include <stdio.h>
int* fun9();
void main() {
int *ptr = fun9();
printf("我是土豪,n的地址的门面我要了,10倍价钱甩你脸上");
printf("ptr=>%d",*ptr);
getchar();
}
int* fun9() {
int n = 100;
return &n;
}
对比之前的代码,我们不过加了一句字符的输出罢了,但是,字符也是占据内存的,这时候,我们再来看一下输出结果:
我们可以看到,ptr指向的n的地址里的值变了,它不是100了,而是一个未知数,因为原先的值被“土豪”覆盖掉了,所以,在函数中返回一个普通的局部变量是非常不严谨的,如果一定要返回的话,那这个局部变量一定得是用static修饰的静态变量,为了证实这一结论,我们给fun9()方法中的局部变量n加上static
#include <stdio.h>
int* fun9();
void main() {
int *ptr = fun9();
printf("我是土豪,n的地址的门面我要了,10倍价钱甩你脸上");
printf("ptr=>%d",*ptr);
getchar();
}
int* fun9() {
static int n = 100;
return &n;
}
运行如下
可以看到,我们加了static之后,n的值任然为100,并没有被覆盖掉,这就相当于我自己就是房东,这个房子我拥有使用权,我想租就租,想自己住就自己住,给再多钱也没用,当然,我这个例子可能并不是特别形象,我们从原理的角度出发: 因为static修饰的变量存储在堆区中的静态区,并不在栈中,所以当fan9()函数被销毁后,static修饰的变量也不会被销毁。它任然是一个有效的数据。
————2021-1-31
fufu记录每一天