C语言--函数-变量

40 阅读5分钟

**# C 语言函数与变量基础

C 语言中变量的作用域、存储类型,以及函数对变量的访问规则,是理解程序运行逻辑的核心基础。以下从变量核心概念函数与变量的交互常见易错点三个维度梳理,结合之前的代码案例帮你彻底理解。

一、变量的核心属性

1. 作用域(变量能被访问的范围)

作用域决定了变量在代码中哪些位置可以被读取 / 修改,分为两类核心类型:

类型定义位置作用范围示例
局部变量函数 / 代码块({})内部仅在定义的函数 / 代码块内有效f()内的int a=1;
全局变量所有函数外部整个程序(所有函数均可访问)int a=200;(函数外)

关键规则:同名覆盖

如果局部变量与全局变量同名,局部变量会覆盖全局变量的作用域(仅在局部范围内)。比如之前的案例:

c

运行

arduino
 体验AI代码助手
 代码解读
复制代码
int a = 200; // 全局
void f() {
    int a = 1; // 局部,覆盖全局a
    a = 2;     // 修改的是局部a,全局a不受影响
    printf("%d", a); // 输出2(局部)
}

2. 存储类型(变量的生命周期)

除了作用域,存储类型决定变量何时创建、何时销毁,核心分为两种:

类型存储位置生命周期初始化规则
自动变量(auto)栈区函数执行时创建,结束销毁不初始化则值为随机数(垃圾值)
全局变量静态区程序运行全程存在未手动初始化则默认赋值为 0

注:局部变量默认是auto类型(可省略auto关键字),比如int a=1;等价于auto int a=1;

二、函数与变量的交互规则

函数对变量的访问 / 修改,核心遵循「先找局部,再找全局」的优先级,结合案例拆解:

规则 1:函数优先访问局部变量

函数内若定义了某变量,优先使用局部版本,全局变量暂时 “失效”。

c

运行

css
 体验AI代码助手
 代码解读
复制代码
int b = 100; // 全局b
void f() {
    int a = 1; // 局部a
    b = 2;     // 无局部b,直接修改全局b
    printf("a=%d, b=%d", a, b); // 输出a=1, b=2
}

规则 2:局部变量无法跨函数访问

函数内的局部变量仅在自身作用域有效,其他函数(包括main)无法访问。比如:

c

运行

csharp
 体验AI代码助手
 代码解读
复制代码
void f() {
    int a = 1; // f的局部a
}
int main() {
    f();
    printf("%d", a); // 报错!main中无a,也访问不到f的局部a
}

规则 3:全局变量可被所有函数修改

全局变量在整个程序中共享,任何函数都能修改其值(需注意全局变量滥用导致的代码混乱)。

c

运行

csharp
 体验AI代码助手
 代码解读
复制代码
int num = 0; // 全局变量
void add() {
    num += 1; // 修改全局num
}
int main() {
    add();
    printf("%d", num); // 输出1
    return 0;
}

三、常见易错点与避坑指南

1. 未初始化的局部变量

局部变量未初始化时,值为随机的垃圾值(栈区残留数据),直接使用会导致程序行为不可控:

c

运行

arduino
 体验AI代码助手
 代码解读
复制代码
void f() {
    int a; // 未初始化
    printf("%d", a); // 输出随机数(如32767、-12345等)
}

✅ 解决:局部变量使用前必须手动初始化(如int a=0;)。

2. 全局变量与局部变量同名混淆

新手易误将局部变量的修改当成全局变量的修改,比如:

c

运行

csharp
 体验AI代码助手
 代码解读
复制代码
int a = 10;
void f() {
    int a; // 局部a(未初始化)
    a = 5; // 修改的是局部a,全局a仍为10
}

✅ 解决:尽量避免全局 / 局部变量同名;若必须同名,可通过注释明确区分。

3. 滥用全局变量

全局变量全程占用内存,且多函数修改时易出现 “偶发 bug”(难以定位哪个函数改了值)。✅ 解决:优先使用局部变量,仅在多个函数需共享且修改频率低时用全局变量。

四、核心总结

  1. 变量访问优先级:局部 > 全局
  2. 局部变量:作用域仅限当前函数 / 代码块,生命周期随函数结束而销毁;
  3. 全局变量:作用域覆盖整个程序,生命周期随程序结束而销毁;
  4. 函数无法跨域访问其他函数的局部变量,仅能通过参数 / 全局变量实现数据传递。

结合之前的案例,再看这段代码就能一眼理清逻辑:

c

运行

css
 体验AI代码助手
 代码解读
复制代码
#include <stdio.h>
int a = 200;
int b = 100;
void f(){
    int a = 1;
    b = 2;
    printf("a=%d, b=%d\n", a, b); // 局部a=1,全局b=2 → 输出a=1, b=2
}
int main(){
    f();
    printf("a=%d, b=%d\n", a, b); // 全局a=200,全局b=2 → 输出a=200, b=2
}
```**



```c
int a = 1;
void f(){
    a = 2;
    printf("在函数f的内部:a=%d", a);
}

int main(){
    f();
    printf("在函数main的内部:a=%d", a);
}
c
 体验AI代码助手
 代码解读
复制代码
void f(){
    int a = 1;
    printf("%d", a);
}

int main(){
    f();
    printf("%d", a);
}

image.png

c
 体验AI代码助手
 代码解读
复制代码
#include <stdio.h>
int a = 200; // 全局

void f() {
    int a = 1; // 局部
    a = 2; // 使用局部变量
    printf("%d\n", a); // 2
}

int main(){
    f();

    // 在main函数中,绝对不可能访问
    // f 中的局部变量
    // 此处的a就是全局变量a
    printf("%d\n", a); // 200
}

image.png

c
 体验AI代码助手
 代码解读
复制代码
#include<stdio.h>
int a = 200;
int b = 100;
void f(){
    int a = 1;
    b = 2;
    printf("a=%d, b=%d\n", a, b);
}

int main(){
    f();
    printf("a=%d, b=%d\n", a, b);
}

image.png

c
 体验AI代码助手
 代码解读
复制代码
#include<stdio.h>
void f(int x, int y){
    x += 1;
    y -= 1;
}

int main(){
    int x = 10;
    int y = 10;
    f(x, y);
    printf("x=%d, y=%d", x, y);
}