C语言变量和函数

变量

局部变量

  在函数或复合语句内部定义的变量叫做局部变量,局部变量只在它定义的函数或复合语句内有效,函数被调用时为局部变量开辟空间并赋值,函数执行完毕后局部变量的空间随即被释放

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <stdio.h>
void numPlus();


int main() {

numPlus();
numPlus();
numPlus();

return 0;
}

void numPlus() {
int num = 100;
for (size_t i = 0; i < 10; i++)
{
num++;
}

// 将会输出 110
printf("num = %d\n", num);
}

  用static修饰的局部变量称为静态局部变量,静态局部变量只在它定义的函数或复合语句内有效,第一次调用函数时为静态局部变量开辟空间并赋值,但是并不会随着函数的执行完毕而释放,并且在后续调用函数时,不再为其开辟空间和赋值。静态局部变量默认值为0

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <stdio.h>
void numPlus();


int main() {

numPlus();
numPlus();
numPlus();

return 0;
}

void numPlus() {
static int num = 100;
for (size_t i = 0; i < 10; i++)
{
num++;
}

// 第一次被调用时输出 110
// 后续输出 120, 130, ...
printf("num = %d\n", num);
}

全局变量

  在函数之外定义的变量叫做全局变量,extern修饰的全局变量表示允许被外部调用,但由于普通全局变量默认允许外部调用,所以extern修饰可有可无。注意全局变量在声明时不要进行定义(赋值)。全局变量默认值为0

1
2
3
4
5
6
#include<stdio.h>
extern int num;

int main (){
num = 100;
}

  static修饰的全局变量表示静态全局变量,静态全局变量禁止外部调用,仅供当前C文件调用,因此extern和static有冲突,不能修饰同一个变量。静态全局变量默认值为0

1
2
3
4
5
6
#include<stdio.h>
static int num;

int main (){
num = 100;
}

函数

入口函数

  入口函数是C语言执行的起点

1
2
3
4
5
6
#include<stdio.h>

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

函数调用

  C语言从入口函数开始执行,但是编译器从上往下编译,当被调函数在下,主调函数在上时,主调函数并不知道被调函数的存在,所以会出现错误

1
2
3
4
5
6
7
8
9
10
11
12
#include<stdio.h>

int main() {
// 此时 fun1 函数没有被定义
fun1();

return 0;
}

void fun1() {
printf("fun1\n");
}

  可以将被调函数fun1放在主调函数main之上,此时被调函数优先编译,当主调函数调用时,已经知道了被调函数的存在

1
2
3
4
5
6
7
8
9
10
11
12
#include<stdio.h>

void fun1() {
printf("fun1\n");
}

int main() {
// 此时 fun1 已经被定义
fun1();

return 0;
}

  或者先对被调函数进行声明,提前告知被调函数的存在,函数虽然只可以定义一次,但可以被声明无数次

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include<stdio.h>

void fun1(); // 声明fun1函数的存在

int main() {
// 此时 fun1 函数虽然没有被定义,但是main函数已经知道它的存在
fun1();

return 0;
}

void fun1() {
printf("fun1\n");
}

  调用其他c文件中的函数时,也需要对其进行声明,例如demo2.c

1
2
3
4
5
#include<stdio.h>

void fun2() {
printf("fun2\n");
}

  当demo1.c中的主调函数调用demo2.c的被调函数时

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h>
void fun1();
extern void fun2();

int main() {
fun1();
fun2();

return 0;
}

void fun1() {
printf("fun1\n");
}

函数声明

  c文件中的函数较少时,可以通过被调函数放在主调函数之上,或者在c文件中声明被调函数的方式,来解决函数未定义的问题,当c文件中函数过多时,大量函数声明将会使代码变得臃肿,函数的循环调用也使得上下顺序摆放不切实际,所以此时可以创建对应的头文件,在头文件中声明函数,在c文件中只声明头文件,例如demo1.c中的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
void fun1();
void fun2();

int main() {
fun1();
fun2();

return 0;
}

void fun1() {
printf("fun1\n");
}

void fun2() {
printf("fun2\n");
}

  创建对应的头文件demo1.h,并在其中声明fun1fun2

1
2
3
4
#include <stdio.h>

extern void fun1();
extern void fun2();

  而在demo1.c中只对demo1.h进行声明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include "demo1.h"

int main() {
fun1();
fun2();

return 0;
}

void fun1() {
printf("fun1\n");
}

void fun2() {
printf("fun2\n");
}

静态函数

  被static修饰的函数称为静态函数,静态函数仅可被当前C文件调用

1
2
3
static void test() {
printf("静态函数");
}