# 1.10 外部变量与作用域

External Variables and Scope

这一节需要用心去体会。 函数中的局部变量只在函数被调用的时候存在，在函数执行完毕退出时消失。

<figure><img src="https://labspc.com/wp-content/uploads/2024/01/1705655292-word-image-273-1.png" alt=""><figcaption></figcaption></figure>

注意这里 蓝色和红色的词。

explicitly 显示地

局部变量，我们没有给它赋值，它存放的就是无效值 garbage，这一点在后文还会具体讲述。

define 是定义，declare 是声明。 二者的不同在于 define 是在创建会分配内存，declare 是在说明性质，并不会分配内存。

<figure><img src="https://labspc.com/wp-content/uploads/2024/01/1705655295-word-image-273-2.png" alt=""><figcaption></figcaption></figure>

这里还要注意的是，extern 的使用要视情况而定，不是说越多越好。

到此，根据《krc-2e》这本书，有关 c 语言的核心内容就讲解完了。后续，会根据教材和我的笔记，进行适当的内容补充。

打印最长文本行程序

{% code title="1.10.1 print-longest-text.c" lineNumbers="true" %}
```c
#include <stdio.h>
#define MAXLINE 1000 /* maximum input line length */

int max;               // 当前的最大行长度
char line[MAXLINE];    // 当前的输入行
char longest[MAXLINE]; // 用于保存最长的行

// ANSI C 要使用 void 显式声明函数的参数表为空
int get_line(void);
void copy(void);

int get_line(void)
{
    int c, i; // c 用于接收输入的字符，i 用于记录当前行的长度
    extern char line[]; // 其实这里是多余的，
    // MAXLINE - 1 保留一个位置给字符串的结束字符 '\0'
    // c != EOF 保证输入的字符不是文件结束符&不是换行符
    for (i = 0; i < MAXLINE - 1 && (c = getchar()) != EOF && c != '\n'; ++i)
        line[i] = c;

    if (c == '\n')
    {
        line[i] = c;
        ++i;
    }

    line[i] = '\0';

    return i;
}

void copy(void)
{
    int i;
    extern char line[], longest[]; // 其实这里是多余的，
    i = 0;
    while ((longest[i] = line[i]) != '\0') // 复制最长的行
        ++i;
}

int main()
{
    int len; 
    // main 外部变量声明
    extern int max;
    // get_line、copy 函数在使用外部变量前，要先知道外部变量的名字，所以要先声明
    extern char longest[];
    max = 0;
    while ((len = get_line()) > 0)
        if (len > max)
        {
            max = len;
            copy();
        }

    if (max > 0) /* there was a line */
        printf("%s", longest);

    return 0;
}
```
{% endcode %}

作用域

<figure><img src="https://labspc.com/wp-content/uploads/2024/01/1705655297-word-image-273-3.png" alt=""><figcaption></figcaption></figure>

全局变量的作用域在整个工程

{% code title="1.10.2 global-var-test.c" lineNumbers="true" %}
```c
#include <stdio.h>

int eg1 = 2; //定义全局变量 eg1


void test()
{
    printf("test-->%d\n", eg1); //test--> 显示的内容
    
}
// 自己写一个test函数，void是函数的返回类型



int main()
{
    test(); //调用 test()
    //printf("test-->%d\n", eg1); eg1=2 这是第一遍
    
    {
        printf("eg1=%d\n", eg1); //打印 第二遍
    }
    
    printf("eg1=%d\n", eg1); //打印 第三遍
    
    return 0;
}
```
{% endcode %}

```
➜  exit;
test-->2
eg1=2
eg1=2
```

生命周期

{% code title="" lineNumbers="true" %}
```c
int main()
{ 
    {
        int eg1 = 22;
        printf("eg1=%d\n", eg1); 
    }
    return 0;
}
```
{% endcode %}

{% code title="" lineNumbers="true" %}
```c
	{
        int eg1 = 22;
        printf("eg1=%d\n", eg1); 
    }
```
{% endcode %}

进入{} 局部变量eg1的生命周期开始，出{} 生命周期结束。 结束，此时局部变量eg1 被销毁。

全局变量的生命周期，这里就不解释了，程序在，他就在。

探讨生命周期的意义在哪里？作用域也是一样，为什么要去探讨？ 我们讨论这个就是，方便我们，知道什么时候，什么变量可以用，什么时候，它被销毁了，用不了。
