课内C语言笔记

Chap1 C语言程序设计概述

本章要点:

1. 程序概念? 程序设计语言发展的几个阶段?

  完成某项任务的一系列具体步骤; 机器语言--汇编语言--高级语言;

2. 算法概念? 算法描述方法? 流程图和伪代码?

  对特定问题求解步骤的一种描述; 自然语言, 流程图, 伪代码;

3. C语言特点?

  面向算法过程的程序设计语言,先分析问题求解过程, 再描述问题求解算法, 最后编程实现;

4. C语言程序的基本框架?

  main函数, 若干自定义函数;

5. C语言的主要语法单位?

  常量, 变量, 运算符, 分隔符, 表达式, 变量定义, 语句, 函数, 输入输出;

6. C语言程序上机步骤?

  源文件(.c)编译成目标程序(.c), 通过连接编程可执行程序(.exe);

7. 实现问题求解的过程? 

  问题分析与算法设计--编辑程序--编译连接--运行与调试;

1.1 程序与程序语言

程序: 完成某项任务的一系列的具体步骤;
             例如: 1.  新生开学典礼程序;
                          2. 中央电视台春节联欢晚会程序;

计算机程序: 用计算机语言描述的解决某一问题的一系列加工步骤, 符合一定语法规则的符号序列, 告诉计算机:A. 处理什么数据--处理数据 ;
                                                                   B. 如何处理数据--处理步骤;

程序设计语言: 计算机语言, 提供编程手段, 提供数据表达和数据处理的两大功能;
发展阶段: 机器语言--汇编语言--高级语言  
高级语言: 1. 面向算法过程的程序设计语言(C语言)
                    编程过程: 分析问题求解过程--描述问题求解算法--编程实现;
                    2. 面向任务的程序设计语言;(SQL语言)
                    无需知道问题如何求解, 只需描述求解什么问题;
                    3. 面向对象的程序设计语言(C++, Java)
                    面向客观事物的设计程序;

1.2 算法及其描述

程序 = 数据结构 + 算法;

算法: 对特定问题求解步骤的一种描述;
             例如: 新生开学典礼算法;

算法描述通常包括: 1. 自然语言;
                                  2. 传统流程图;
                                  3. 结构化流程图;(N-S流程图)
                                  4. 伪代码;(介于自然语言与计算机语言之间的文字)

1.3 C语言的发展与特点


发展历史: 1972发明C语言--1978旧标准C语言--1983新标准C语言;

特点: 结构化, 简洁灵活, 易移植, 强大处理能力, 代码运行效率高等;

注意: C语言中大小写字母代表不同含义;

1.4 简单C语言程序

要点: 1. 只由main函数构成的简单程序;
            2. 由main函数调用另一个函数构成的简单程序;
            3. C语言程序的基本结构;

例1: 输出"Hello World!";
  运行: 程序从main函数开始运行, 当main函数运行结束, 程序运行结束;
  组成: 程序由函数组成, 有且必须有一个主函数main函数;

#include <stdio.h>

int main()
{
    printf("Hello World!");

    return 0;
}

例2: n!阶乘问题;
  组成: main函数带若干自定义函数组成, 有且必须有一个主函数main函数;

#include <stdio.h>

int fact(int n)
{
    int i, res = 1;
    for (i = 1; i < n; i ++)
    {
        res *= i;
    }
    
    return res;
}

int main()
{
    int n, res;
    
    printf("Input n: ");
    scanf("%d", &n);
    res = fact(n);
    printf("%d! = %d\n", n, res);

    return 0;
}

C语言程序构成: 一个完整的C语言程序由一个main函数带若干个用户自定义函数所构成;

1.5 C语言简介

C语言的功能: 1. 数据表达: 表达所要处理的数据;
                           2. 流程控制: 表达数据处理的流程;

1. 数据表达

通过数据类型来实现;

数据类型: 共同特点的数据集合的总称, 涉及数据定义和数据运算两个方面;
               例如: 整数类型--int
                            数据定义: {..., -2, -1, 0, 1, 2, ...}, 有限范围;
                            数据运算: + - * / %等运算操作;

=================(此处贴数据类型)

基本类型:  程序设计语言事先已经定义好,
               包括: 1. 整型--int;
                            2. 实型--float, double;
                            3. 字符型--char;
               构造类型: 程序员通过使用基本类型来构造复杂类型,
                                    包括: 数组, 结构, 共用体, 枚举,指针, 链表, 文件;

2. 流程控制

程序通常可以通过3种基本控制结构组合而成;

语句级控制: 三种基本控制结构;
                   顺序结构: 顺序执行模块;
                   分支结构: 也叫选择结构, 根据条件选择执行模块;
                   循环结构: 也叫重复结构, 根据条件重复执行模块;

单位级控制: 函数结构;
                   复杂问题: 将程序分为若干相对独立的子程序(函数);

标题3: C语言的语法

C语言字符集: C语言编程能使用的字符集是固定的, 有限的,
                      包括: 1. 英文字母, 大小写字母共52个;
                                   2. 阿拉伯数字, 共10个;
                                   3. 下划线,_;

C语言标识符: 标识符: 由字母, 数字及下划线组成的字符序列, 且首字符必须是字母或下划线;
两类标识符: 1. 保留字: C语言规定的, 赋予特定含义, 有专门用途的标识符,不能作其它用途, 如printf, if, for;
                       2. 自定义标识符: 程序中自定义的变量名, 类型名, 函数名, 常量名, 常用英文单词或缩写。

C语言的语法: (1)常量;
                         (2)变量;
                         (3)运算符;
                         (4)分隔符;
                         (5)表达式;
                         (6)变量定义;
                         (7)语句:1. 表达式语句;
                                             2. 分支语句;
                                             3. 循环语句;
                                             4. 复合语句: 大括号内的语句;
                         (8)函数;
                         (9)输入输出;

C语言上机步骤: 源文件(.c)编译成目标程序(.c), 通过连接编程可执行程序(.exe)

1.6 实现问题求解的过程

1. 问题分析与算法设计

例如: 求1-100范围内, 满足3的倍数的若干整数的个数;

思路: 设置计数器count, 初值为0, 让变量i在1-100的整数范围内变化寻找3的倍数并计数到count中;

2. 编辑程序

将算法翻译成C源程序;

3. 编译链接

编译程序: 对源程序进行编译, 生成二进制代码, 指出语法错误(编译错误);
连接程序: 将目标程序与编程环境提供的库函数连接, 指出连接错误;

4. 运行与测试(经验)

逻辑错误: 也称语义错误, 指运行程序导致运行结果不正确;

调试程序: 在程序中查找错误并改正错误的过程,主要方法:
                    1. 设置断点;
                    2. 单步跟踪;

调试工作: 需要耐心和经验, 是程序设计最基础的技能之一;

总结: C语言程序调试, 运行步骤;

=========此处贴一个流程图=========

Chap2 C语言简单程序设计

本章要点:

1. 编写程序在屏幕上显示信息;

2. 编写程序实现简单的数据处理;

3. 使用if-else语句编程计算二分段函数;

4. 使用for语句实现指定次数的简单循环结构程序;

2.1 在屏幕上显示信息

例1: 在屏幕上显示一个短句: Hello World!;
    1. 任何程序都有主函数main;
    2. 程序由若干语句组成;
    3. 语句由;结束;

  main函数头格式定义: 函数类型 main(函数参数);
  void用法: 函数类型表示无返回值, 参数表示无参数;
=========此处贴代码========

2.2 求三角形面积(顺序结构)

例2: 输入三角形的底a和高h, 求三角形的面积;
  函数体构成: IPO结构
  I: 主要由变量, 函数声明或数据输入;
  P: 数据处理, 主体;
  O: 结果输出或返回结果;

=========此处贴代码=========

2.3 计算分段函数(分支结构)

2.4 输出华氏--摄氏转换表(循环结构)

Chap8 指针

本章要点:

1. 变量, 内存单元和地址之间是什么关系?

2. 如何定义指针变量, 怎样使用指针变量?

3. 什么是指针变量的初始化?

4. 指针基本运算? 如何通过指针操作所值变量?

5. 指针作为函数参数的原理与作用?

6. 如何使用指针实现函数调用返回多个值?

7. 指针数组: 指针数组与二级指针的关系? 如何使用指针数组处理多个字符串?

关于指针: 1. 重要数据类型; 2. C语言精华; 3. 复杂数据结构;
       用途: 1. 实现动态内存分配;
                2. 使用数组和字符串;
                3. 实现函数间各类数据的传递;

8.1 指针与指针变量

1. 引例: 如何获取银行卡密码问题

问题描述: 密码888在编号1000key抽屉, key抽屉编号1000在编号2000addr抽屉, 如何获取密码?

方法一: 直接获取: 通过key抽屉的名字, 直接取出key抽屉的内容(888);
                             printf("%d", key);

方法二: 间接获取: addr抽屉指向key抽屉, 通过addr抽屉, 间接取出key抽屉的内容(888);
                             printf("%d", *addr);

例1: 利用指针模拟寻找银行卡密码的过程;

#include <stdio.h>

int main()
{
    int key = 888; // 密码
    int *addr = &key; // 地址, 这个指针指向key

    printf("The key is %d\n", key); // 直接访问
    printf("The key is %d\n", *addr); // 间接访问

    return 0;
}

2. 地址与指针 -- 指针的概念

指针: 变量的内存单元地址, 即内存单元编号;

变量的值与地址不同;
变量x: 地址1000, 值20;
变量y: 地址1002, 值1;
变量p: 地址2000, 值1000(x的地址);

3. 指针变量的定义: 类型名 * 指针变量名

类型名: 指针变量所指变量的类型; *是指针声明符;

例如: int * p; 指针变量名是p, 不是*p;

注意: 定义多个指针变量, 每个变量前都必须加上*, 不能简写;

指针初始化: 使指针变量指向普通的值变量, 例如int *p = &a;

4. 指针的基本运算

1. 取地址运算&(给出变量的地址)

注意: 指针变量类型和所指变量类型必须相同;

2. 间接访问运算*(访问指针所指向的变量)

*p: 指针变量p所指向的变量, 即变量a;

注意: 指针变量类型和所指变量类型必须相同;

例2: 指针取地址运算和间接访问运算

#include <stdio.h>

int main()
{
    int a = 3, *p;
    
    p = &a;
    printf("a = %d, *p = %d\n", a, *p);
    *p = 10;
    printf("a = %d, *p = %d\n",a, *p);
    scanf("%d", &a);
    printf("a = %d, *p = %d\n", a, *p);
    (*p)++;
    printf("a = %d, *p = %d\n", a, *p);

    return 0;
}

程序运行结果: 

相关说明: 

3. 赋值运算

#include <stdio.h>

int main()
{
    int a = 3, *p1, *p2;
    
    p1 = &a; // 把a的地址赋给p1, 即p1指向a
    p2 = p1; // p2也指向a

    return 0;
}

注意: 只有同类型指针才能相互赋值;

8.2 指针与函数

1. 引例

例3: 交换两个变量值的问题;

问题描述: 两个变量a和b, 如何实现a, b互换?
                三个函数: swap1(), swap2(), swap3();
分析: swap1(), swap2(), swap3()三个函数, 谁能实现交换功能?

#include <stdio.h>

int main()
{
    void swap1(int x, int y), swap2(int *px, int *py), swap3(int *px, int *py);
    
    int a = 1, b = 2;
    
    swap1(a, b);
    printf("After calling swap1: a = %d b = %d\n", a, b);
    
    a = 1; b = 2;
    swap2(a, b);
    printf("After calling swap2: a = %d b = %d\n", a, b);
    
    a = 1; b = 2;
    swap3(a, b);
    printf("After calling swap3: a = %d b = %d\n", a, b);

    return 0;
}

2. 指针作为函数参数

swap1()函数:

swap2()函数:

swap3()函数:

结论: 被调函数如何改变主调函数中变量的值? 必须满足:
          1. 传址方式: 形参是指针变量, 实参是变量地址, 传地址;
          2. 间接访问: 被调函数间接访问, 改变形参所指的实参变量;

例4: 通过指针实现函数调用返回多个值;

问题描述: 输入年和天数, 输出对应的日期, 如输入2000和61, 输出2000-3-1;
要求: 定义函数month_day(), 根据年和天数, 计算并返回对应的日期(两个值: 月, 日);

#include <stdio.h>

void month_day(int year, int yearday, int *pmonth, int *pday)
{
    int k, leap;
    int tab[2][13] = { {0, 31, 28, 31, 30, 31, 30, 31, 30, 31, 30, 31}, // 是闰年
                       {0, 31, 29, 31, 30, 31, 30, 31, 30, 31, 30, 31} }; // 不是闰年

    // 计算闰年标志leap
    leap = (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;

    for (k = 1; yearday > tab[leap][k]; k++) // 计算对应的月和日
    yearday = yearday - tab[leap][k];

    *pmonth = k; // 间接访问, 返回月
    *pday = yearday; // 间接访问, 返回日

}
int main()
{
    int day, month, year, yearday;
    
    printf("Input year and yearday:");
    scanf("%d%d", &year, &yearday);
    month_day(year, yearday, &month, &day);
    printf("%d-%d-%d\n", year, month, day);

    return 0;
}

3. 指针作为函数返回值

指针函数: 指针作为函数的返回值, 返回各种类型的指针数据;

定义格式: 类型标识符 * 函数名 (形式参数表)

int * fun(int a, int b)
{
    函数体语句;
  
    return (指针);
}

例5: 设计一个指针函数min, 返回指向两个整数中最小值的地址;

#include <stdio.h>

int * min(int x, int y)
{
    int *p;

    if (x < y) p = &x;
    else p = &y;

    return (p); // 返回最小值变量的地址
}

int main()
{
    int x, y, *p;
    
    printf("Input x and y:");
    scanf("%d%d", &x, &y);
    p = min(x, y); // 函数调用
    printf("The min is %d\n", *p); // 输出结果

    return 0;
}

思考: *p访问正确吗?
答: 并不安全, 因为x和y是局部变量, 它们的地址在函数min结束后可能变得无效, 在这种情况下, *p的值是未定义的;

修改后的代码

#include <stdio.h>

int * min(int *x, int *y)
{
    int *p;

    if (*x < *y) p = x;
    else p = y;

    return (p); // 返回最小值变量的地址
}

int main()
{
    int x, y, *p;
    
    printf("Input x and y:");
    scanf("%d%d", &x, &y);
    p = min(&x, &y); // 函数调用
    printf("The min is %d\n", *p); // 输出结果

    return 0;
}

4. 指向函数的指针

函数入口地址: 函数包括一组语句, 运行时存储在程序区的某内存段, 该段内存的起始地址为函数入口地址;

函数名: 函数入口地址;

函数指针: 指针变量, 专用指向函数;
定义形式: 类型标识符 (*指针变量名) (形参表);
例如: int (*p) (int, int);
作用: 定义函数指针变量p, 指向int类型函数;

函数指针赋值: 将函数入口地址赋给函数指针, 格式: 指针变量名 = 函数名;

函数调用: 两种形式
1. 函数名形式: 函数名(实参表) 例如: a = max(x, y);
2. 函数指针形式: (*函数指针变量名)(实参表) 例如: a = (*p)(x, y);

例6: 函数指针的应用

问题描述: 设计两个函数max()和min(), 求两个整数的最大值和最小值; 在主函数中定义一个函数指针变量p, 通过指针p间接调用max()和min()函数, 并输出调用结果;

#include <stdio.h>

int max(int *x, int *y)
{
    if (*x > *y) return *x;
    else return *y;
}

int min(int *x, int *y)
{
    int (x < y) return *x;
    else return *y;
}

int main()
{
    int a, b, res1, res2;
    int (*p)(int, int);
    
    p = max;
    res1 = (*p)(a, b);
    p = min;
    res2 = (*p)(a, b);

    printf("%d, %d\n", res1, res2);

    return 0;
}

8.3 指针与数组

1. 指向一维数组的指针

#include <stdio.h>

int main()
{
    int a[5] = {1, 2, 3, 4, 5};
    int *p;

    p = a; // p指向数组a
    p = &a[0]; // p指向a[0]
    
    return 0;
}

注意: 数组名a为指针常量, 不变; p为指针变量, 可变;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值