复习--C语言程序基础知识

开源AI·十一月创作之星挑战赛 10w+人浏览 556人参与

一、变量的作用域和生命周期

1. 什么是作用域?

作用域就是变量在代码中的"可见范围",决定了在哪些地方可以使用这个变量。

2. 局部变量

定义位置:在函数内部定义的变量
作用范围:只在定义它的那对大括号 {} 内有效

#include <stdio.h>

void test()
{
    int a = 10;        // 局部变量a,只在test函数内有效
    printf("%d", a);   // 这里可以访问a
}

int main()
{
    test();
    // printf("%d", a);  // 错误!这里不能访问a
    return 0;
}

3. 全局变量

定义位置:在所有函数外面定义的变量
作用范围:从定义位置开始,到整个程序结束

#include <stdio.h>

int global_num = 100;  // 全局变量

void fun1()
{
    global_num = 200;  // 可以修改全局变量
}

void fun2()
{
    printf("%d", global_num);  // 可以访问全局变量
}

int main()
{
    fun1();
    fun2();  // 输出200
    return 0;
}

4. 变量生命周期

生命周期:变量从创建到销毁的时间

局部变量生命周期

  • 开始:执行到变量定义时

  • 结束:离开所在的大括号时

全局变量生命周期

  • 开始:程序启动时

  • 结束:程序退出时

#include <stdio.h>

void test()
{
    int a = 0;        // 每次调用test都会重新创建a
    static int b = 0; // static变量只创建一次
    
    a++;
    b++;
    printf("a=%d, b=%d\n", a, b);
}

int main()
{
    test();  // 输出:a=1, b=1
    test();  // 输出:a=1, b=2
    test();  // 输出:a=1, b=3
    return 0;
}

二、函数参数传递

1. 值传递(传值)

把变量的值复制一份传给函数,函数内修改不会影响原变量。

#include <stdio.h>

void change(int x)    // x是num的副本
{
    x = 100;         // 修改的是副本
    printf("函数内: x=%d\n", x);
}

int main()
{
    int num = 10;
    printf("调用前: num=%d\n", num);  // 输出10
    change(num);
    printf("调用后: num=%d\n", num);  // 还是10,没变!
    return 0;
}

2. 地址传递(传地址)

把变量的地址传给函数,函数可以通过地址修改原变量。

#include <stdio.h>

void change(int *x)   // x是指针,存放地址
{
    *x = 100;         // 通过地址修改原变量
}

int main()
{
    int num = 10;
    printf("修改前: num=%d\n", num);  // 输出10
    change(&num);     // 传递num的地址
    printf("修改后: num=%d\n", num);  // 输出100,变了!
    return 0;
}

3. 数组作为参数

数组作为参数时,传递的是数组的地址。

#include <stdio.h>

// 打印数组
void print_array(int arr[], int size)
{
    for(int i = 0; i < size; i++)
    {
        printf("%d ", arr[i]);
    }
    printf("\n");
}

// 修改数组(会改变原数组)
void double_array(int arr[], int size)
{
    for(int i = 0; i < size; i++)
    {
        arr[i] = arr[i] * 2;
    }
}

int main()
{
    int numbers[5] = {1, 2, 3, 4, 5};
    
    printf("原数组: ");
    print_array(numbers, 5);
    
    double_array(numbers, 5);
    
    printf("修改后: ");
    print_array(numbers, 5);
    
    return 0;
}

三、函数递归

1. 什么是递归?

函数自己调用自己。

递归三要素

  1. 结束条件 - 什么时候停止

  2. 递归调用 - 调用自己

  3. 问题简化 - 每次调用问题要变小

2. 简单递归示例

#include <stdio.h>

// 示例1:倒数
void count_down(int n)
{
    if(n < 0) return;      // 结束条件
    printf("%d ", n);
    count_down(n - 1);     // 递归调用
}

// 示例2:求1+2+...+n的和
int sum(int n)
{
    if(n == 1) return 1;   // 结束条件
    return n + sum(n - 1); // 递归调用
}

int main()
{
    printf("倒数: ");
    count_down(5);         // 输出:5 4 3 2 1 0
    printf("\n");
    
    printf("1+2+3+4+5 = %d\n", sum(5));  // 输出15
    return 0;
}

四、宏定义和预处理

1. 基本宏定义

#include <stdio.h>

// 无参宏
#define PI 3.14
#define MAX_SIZE 100

// 带参宏
#define SQUARE(x) ((x) * (x))
#define MAX(a, b) ((a) > (b) ? (a) : (b))

int main()
{
    double r = 5.0;
    double area = PI * r * r;
    printf("圆面积: %.2f\n", area);
    
    int num = 5;
    printf("%d的平方: %d\n", num, SQUARE(num));
    
    printf("5和3的最大值: %d\n", MAX(5, 3));
    
    return 0;
}

2. 条件编译

根据条件决定编译哪些代码。

#include <stdio.h>

#define DEBUG 1  // 1表示调试模式,0表示发布模式

int main()
{
    int x = 10, y = 20;
    
#ifdef DEBUG
    printf("调试信息: x=%d, y=%d\n", x, y);  // 调试时显示
#endif
    
    int result = x + y;
    printf("结果: %d\n", result);
    
    return 0;
}

3. 头文件保护

防止头文件被重复包含。

// 在my_header.h文件中这样写:
#ifndef _MY_HEADER_H_    // 如果没定义过_MY_HEADER_H_
#define _MY_HEADER_H_    // 就定义它

// 头文件内容...
extern int add(int a, int b);

#endif                   // 结束

五、重要概念总结

1. 变量类型对比

类型作用域生命周期存储位置
局部变量函数内函数执行期间栈区
静态局部变量函数内整个程序数据区
全局变量整个程序整个程序数据区

2. 参数传递对比

方式特点是否影响原变量
值传递传递副本不影响
地址传递传递地址影响

3. 编程建议

  1. 尽量使用局部变量,避免全局变量

  2. 宏定义中的参数要用括号括起来

  3. 递归一定要有结束条件

  4. 头文件要加保护,防止重复包含

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值