C 语言基础

C

计算机组成

计算机结构组成

  • 输入设备
  • 输出设备
  • 中央处理器 (CPU)
    • 运算器
    • 控制器
    • 寄存器
  • 存储器
    • 内存储器
    • 外存储器
  • 示意图
    C

计算机系统组成

  • 硬件系统

    • 主机
      • 中央处理器
        • 运算器
        • 控制器
        • 寄存器
      • 内存储器
        • 只读存储器
        • 随机存储器
    • 外部设备
      • 输入设备
      • 输出设备
      • 外存储器
  • 软件系统
    • 系统软件
      • 操作系统
      • 语言处理系统
      • 系统服务程序
      • 数据库管理系统
    • 应用软件
      • 文字处理软件
      • 表格处理软件
      • 辅助设计软件
      • 实时控制软件

CPU 内部结构与寄存器

  • 64 位和 32 位系统区别
    • 寄存器是 CPU 内部最基本的存储单元
    • CPU 对外是通过总线 (地址、控制、数据) 来和外部设备交互的,总线的宽度是 8 位,同时 CPU 的寄存器也是8位,那么这个 CPU 就叫 8 位 CPU
      • 32 位 CPU:如果总线是 32 位,寄存器也是 32 位,那么这个 CPU 就是 32 位 CPU
      • 准 32 位 CPU:有一种 CPU 内部的寄存器是 32 位,但总线是 16 位,那么这个 CPU 就是准 32 位 CPU
    • 所有的 64 位 CPU 兼容 32 位的指令,32 位兼容 16 位的指令,所以在 64 位的 CPU 上可以识别 32 位的指令

    • 在 64 位 CPU 的架构上运行了 64 位的软件操作系统,那么这个系统就是 64 位

      • 在 64 位的 CPU 架构上,运行了 32 位的软件操作系统,那么这个系统就是 32 位
      • 64 位的软件不能运行在 32 位的 CPU 上
  • 寄存器名字
    • 示意图
      C
  • 寄存器、缓存、内存三者关系
    • 按与 CPU 远近来分
      • 由近到远分别是:CPU 寄存器 缓存 内存
    • CPU 计算时,先预先把要用的数据从硬盘读到内存,然后再把即将要用的数据读到寄存器。
      • 信息交换的关系:CPU 寄存器 内存
    • 缓存的作用
      • 如果经常操作内存中的同一地址的数据,就会影响速度。于是就在寄存器与内存之间设置一个缓存
      • 因为从缓存提取的速度远高于内存。当然,缓存的价格肯定远高于内存

C 语言概述

贝尔实验室发明了最初的 C 语言。

C 语言特点

  • 优点
    • 代码量小
    • 执行速度快
    • 功能强大
    • 编程自由
  • 缺点
    • 写代码实现周期长
    • 可移植性较差
    • 过于自由,经验不足易出错
    • 对平台库依赖较多

C 语言标准

  • K&R C

    起初,C 语言没有官方标准。1978年由美国电话电报公司(AT&T)贝尔实验室正式发表了C语言。布莱恩·柯林汉(Brian Kernighan) 和 丹尼斯·里奇(Dennis Ritchie) 出版了一本书,名叫《The C Programming Language》。这本书被 C语言开发者们称为 K&R,很多年来被当作 C 语言的非正式的标准说明。人们称这个版本的 C 语言为 K&R C。

  • ANSI C/C89 标准

    1989年,美国国家标准协会(ANSI)通过了 C 语言标准,被称为 ANSI X3.159-1989 “Programming Language C”。因为这个标准是1989年通过的,所以一般简称 C89 标准。有些人也简称 ANSI C,因为这个标准是美国国家标准协会(ANSI)发布的。
    1990年,国际标准化组织(ISO)和国际电工委员会(IEC)把 C89 标准定为 C 语言的国际标准,命名为 ISO/IEC 9899:1990 – Programming languages — C[5] 。因为此标准是在1990年发布的,所以有些人把简称作 C90 标准。不过大多数人依然称之为 C89 标准,因为此标准与 ANSI C89 标准完全等同。

    • 美国国家标准协会 (ANSI),推出了 C89
    • 国际标准化组织 (ISO) 和国际电工委员会 (ICE),推出了 C90
  • C99 标准

    1999年1月,国际标准化组织(ISO)和国际电工委员会(IEC)发布了 C 语言的新标准,名叫 ISO/IEC 9899:1999 – Programming languages — C ,简称 C99 标准。这是 C 语言的第二个官方标准。

    • 国际标准化组织 (ISO) 和国际电工委员会 (ICE),推出了 C99

C 语言关键字、控制语句和运算符

第一个 C 语言程序

打印 hello world

  • 使用 VS (visual studio) 创建新项目
    • 新建项目-空项目
    • 解决方案资源管理器-源文件-新建项-C++ 文件(.cpp)
      C
    • 调试-开始执行 ctrl+F5
  • 示例:hello_world.c
    #include   // #:关键标识符,表示引入头文件;include:引入头文件关键字
    #include   // :表示使用系统库函数。"":表示用户自定义库函数。
    
    int main(void)      // int:函数返回值是整形数据。
                                // main:函数名。程序唯一的入口。必须有,且只有一个。
                                // void:函数调用无需传参。
    {                           // {:函数体,起始位置
        printf("hello world\n");    // printf:函数,将字符串输出到屏幕上,需要头文件 。 \n:回车换行
        Sleep(2000);                        // 休眠2000毫秒,需要头文件 
        //system("mspaint");
        system("pause");        // 调用 system 函数实现暂停功能。
        return 0;                   // 返回当前函数调用。退出程序。 0 要跟 main 函数的返回值一一对应
    }                           // }:函数体,结束位置
    
    • C 语言的源文件是一个普通的文本文件,但扩展名必须是 .c
    • 注释
      • 单行注释
        • //
      • 多行注释 (块注释)
        • /**/

解决提示框一闪而过

  • 通过 system() 函数

    “`C++

    <h1>include</h1>

    int main(void)
    {
    printf("hello world\n");
    system("pause"); // 调用系统命令,使暂停
    return 0;
    }

    “`

    Note: 清屏命令 cls

  • 借助 VS 工具

    • 项目右键属性-链接器-系统-子系统-控制台 (/SUBSYSTEM:CONSOLE)
      C

gcc 编译

我们用编辑器编写程序,由编译器编译后才可以运行。
编译器是将易于编写、阅读和维护的高级计算机语言编译成计算机能解读、运行的低级机器语言的程序。

编译步骤

#include <stdio.h>  // 头文件展开
#define PI 3.14        // 宏定义替换

int main()
{
#if 1                  // 展开条件编译
    printf("hello world\n");  // 替换注释
#endif
    return 0;
}
  • 示意图
    C

  • 预处理

    gcc -E hello.c -o hello.i
    

    生成 hello.i 预处理文件,文件内容:

    ...
    extern void funlockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__));
    # 864 "/usr/include/stdio.h" 3 4
    extern int __uflow (FILE *);
    extern int __overflow (FILE *, int);
    # 879 "/usr/include/stdio.h" 3 4
    
    # 2 "hello.c" 2
    
    
    
    # 4 "hello.c"
    int main()
    {
    
     printf("hello world\n");
    
     return 0;
    }
    
    • 头文件展开
      • 不检查语法错误
      • 可以展开任意文件
    • 宏定义替换
      • 将宏名替换为宏值
    • 替换注释
      • 变成空行
    • 展开条件编译
      • 根据条件展开指令
    • 其他

  • 编译

    gcc -S hello.i -o hello.s
    

    生成 hello.s 汇编文件,文件内容:

            .file   "hello.c"
            .text
            .section        .rodata
    .LC0:
            .string "hello world"
            .text
            .globl  main
            .type   main, @function
    main:
    .LFB0:
            .cfi_startproc
            pushq   %rbp
            .cfi_def_cfa_offset 16
            .cfi_offset 6, -16
            movq    %rsp, %rbp
            .cfi_def_cfa_register 6
            movl    .LC0, %edi
            call    puts
            movl0, %eax
            popq    %rbp
            .cfi_def_cfa 7, 8
            ret
            .cfi_endproc
    .LFE0:
            .size   main, .-main
            .ident  "GCC: (GNU) 8.3.1 20191121 (Red Hat 8.3.1-5)"
            .section        .note.GNU-stack,"",@progbits
    
    • 逐行检查语法错误
      • 是整个编译 4 步骤中最耗时的步骤
    • 将 C 程序翻译成汇编指令

  • 汇编

    gcc -c hello.s -o hello.o
    

    生成目标文件 hello.o,文件内容是二进制编码:

    [root@yingzai ~]$ strings hello.o
    hello world
    GCC: (GNU) 8.3.1 20191121 (Red Hat 8.3.1-5)
    hello.c
    main
    puts
    .symtab
    .strtab
    .shstrtab
    .rela.text
    .data
    .bss
    .rodata
    .comment
    .note.GNU-stack
    .rela.eh_frame
    
    • 翻译
      • 将汇编指令翻译成对应的二进制编码
  • 链接
    gcc hello.o -o hello.exe
    

    生成可 hello.exe 执行文件,文件内容:

    [root@yingzai ~]strings hello.exe 
    /lib64/ld-linux-x86-64.so.2
    dV:ZS3
    libc.so.6
    puts
    __libc_start_main
    GLIBC_2.2.5
    _ITM_deregisterTMCloneTable
    __gmon_start__
    _ITM_registerTMCloneTable
    []A\A]A^A_
    hello world
    ;*3"
    GCC: (GNU) 8.3.1 20191121 (Red Hat 8.3.1-5)
    3h921
    3c921
    ...
    
    • 数据段合并
    • 数据地址回填
    • 库引入

跨步骤执行

查看依赖库

  • Windows
  • Linux
    # ldd xxx.so
    # ldd + 可执行程序
    [root@yingzai bin]$ ldd server 
            linux-vdso.so.1 (0x00007ffd50dd0000)
            libc.so.6 => /lib64/libc.so.6 (0x00007f2021be8000)
            /lib64/ld-linux-x86-64.so.2 (0x00007f2021fab000)
    

汇编语言

VS 中 C 语言嵌套汇编代码

  • 代码示例:两个整型求和

    “`c++

    <h1>include</h1>

    /*
    int main()
    {
    int a;
    int b;
    int c;

    <pre><code>__asm
    {
    mov a,3
    mov b,4
    mov eax,a
    add eax,b
    mov c,eax
    }

    printf("%d\n", c);

    return 0;
    </code></pre>

    }
    */

    int main(void)
    {
    int a = 3; // 定义整型变量 a,赋初值 3
    int b = 5; // 定义整型变量 b,赋初值 5
    int c; // 定义整型变量 c,无初值

    <pre><code>c = a + b; // 将 a + b 的结果赋值给 c

    printf("%d\n", c); // %d: 格式匹配符,匹配整型数据
    printf("c = %d\n", c);
    printf("%d + %d = %d\n", a, b, c);
    printf("%d + %d = %d\n", a, b, a + b);
    </code></pre>

    }

    “`

VS 反汇编

  • 调试程序

    • 设置断点
      • 行号前
        • 设置显示行号
          C
      • 停止的位置,表示暂未执行

    • 逐语句执行下一条 (F11)

      • 进入函数内部,逐条执行跟踪
    • 逐过程执行下一条 (F10)
      • 不进入函数内部
    • 添加监视 (首先设置断点)
      • 运行调试
      • 调试-窗口-监视
        • 输入监视的值,自动监视
          C
      • 调试-窗口-反汇编
        • 监视汇编执行
          C

集成开发环境 IDE

集成开发环境 (IDE,Integrated Development Environment)。
是用于提供程序开发环境的应用程序,一般包括:

  • 代码编辑器
  • 编译器
  • 调试器
  • 图形用户界面工具

IDE 集成了代码编写功能、分析功能、编译功能、调试功能等一体化的开发软件服务套件,所有具备这一特性的软件或套件都可以叫集成开发环境。

Qt Creator

Qt Creator 是跨平台的 Qt IDE。
Qt Creator 是 Qt 被 Nokia 收购后推出的一款新的轻量级集成开发环境。能够跨平台运行,支持的系统包括 Linux、Mac OS X 以及 Windows。

Microsoft Visual Studio (VS)

是微软的开发工具包。VS 是一个基本完整的开发工具集,包括了整个软件生命周期中所需的大部分工具,如 UML 工具、代码管控工具、集成开发环境 IDE 等。
VS 所写的目标代码适用于微软支持的所有平台。
VS 是目前最流行的 Windows 平台应用程序的集成开发环境。

英仔
版权声明:本站原创文章,由 英仔 2022-08-03发表,共计4961字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)