C语言学习

这篇文章是C语言的入门教程,涵盖了C语言的基本概念,包括C语言的起源、为什么使用C语言、C11标准的新特性,以及C语言的程序结构、基本语法、数据类型、变量、常量、存储类、函数、作用域规则、数组、枚举、指针、函数指针和回调函数。文章还讨论了如何在C程序中声明和使用变量,以及C语言中的输入和输出操作。
摘要由CSDN通过智能技术生成

C语言学习-菜鸟教程

原文链接:https://www.runoob.com/cprogramming/c-structures.html

c简介

  • C 语言是一种通用的高级语言,最初是由丹尼斯·里奇在贝尔实验室为开发 UNIX 操作系统而设计的。C 语言最开始是于 1972 年在 DEC PDP-11 计算机上被首次实现。

  • 在 1978 年,布莱恩·柯林汉(Brian Kernighan)和丹尼斯·里奇(Dennis Ritchie)制作了 C 的第一个公开可用的描述,现在被称为 K&R 标准。

  • UNIX 操作系统,C编译器,和几乎所有的 UNIX 应用程序都是用 C 语言编写的。由于各种原因,C 语言现在已经成为一种广泛使用的专业语言。

    • 易于学习。

    • 结构化语言。

    • 它产生高效率的程序。

    • 它可以处理底层的活动。

    • 它可以在多种计算机平台上编译。

关于c

  • C 语言是为了编写 UNIX 操作系统而被发明的。
  • C 语言是以 B 语言为基础的,B 语言大概是在 1970 年被引进的。
  • C 语言标准是于 1988 年由美国国家标准协会(ANSI,全称 American National Standard Institute)制定的。
  • 截至 1973 年,UNIX 操作系统完全使用 C 语言编写。
  • 目前,C 语言是最广泛使用的系统程序设计语言。
  • 大多数先进的软件都是使用 C 语言实现的。
  • 当今最流行的 Linux 操作系统和 RDBMS(Relational Database Management System:关系数据库管理系统) MySQL 都是使用 C 语言编写的。

为什么使用c语言

C 语言最初是用于系统开发工作,特别是组成操作系统的程序。由于 C 语言所产生的代码运行速度与汇编语言编写的代码运行速度几乎一样,所以采用 C 语言作为系统开发语言。下面列举几个使用 C 的实例:

  • 操作系统
  • 语言编译器
  • 汇编器
  • 文本编辑器
  • 打印机
  • 网络驱动器
  • 现代程序
  • 数据库
  • 语言解释器
  • 实体工具

C11

  • C11(也被称为C1X)指ISO标准ISO/IEC 9899:2011,是当前最新的C语言标准。在它之前的C语言标准为C99。

  • 新特性

    • 对齐处理(Alignment)的标准化(包括_Alignas标志符,alignof运算符,aligned_alloc函数以及<stdalign.h>头文件)。

    • _Noreturn 函数标记,类似于 gcc 的 attribute((noreturn))。

    • _Generic 关键字。

    • 多线程(Multithreading)支持,包括:
      _Thread_local存储类型标识符,<threads.h>头文件,里面包含了线程的创建和管理函数。
      _Atomic类型修饰符和<stdatomic.h>头文件。

    • 增强的Unicode的支持。基于C Unicode技术报告ISO/IEC TR 19769:2004,增强了对Unicode的支持。包括为UTF-16/UTF-32编码增加了char16_t和char32_t数据类型,提供了包含unicode字符串转换函数的头文件<uchar.h>。

    • 删除了 gets() 函数,使用一个新的更安全的函数gets_s()替代。

    • 增加了边界检查函数接口,定义了新的安全的函数,例如 fopen_s(),strcat_s() 等等。

    • 增加了更多浮点处理宏(宏)。

    • 匿名结构体/联合体支持。这个在gcc早已存在,C11将其引入标准。

    • 静态断言(Static assertions),_Static_assert(),在解释 #if 和 #error 之后被处理。

    • 新的 fopen() 模式,(“…x”)。类似 POSIX 中的 O_CREAT|O_EXCL,在文件锁中比较常用。

    • 新增 quick_exit() 函数作为第三种终止程序的方式。当 exit()失败时可以做最少的清理工作。

C 程序结构

  • C 程序主要包括以下部分:

    • 预处理器指令

    • 函数

    • 变量

    • 语句 & 表达式

    • 注释

  • 实例讲解

    • helloworld

      #include <stdio.h>
       
      int main()
      {
         /* 我的第一个 C 程序 */
         printf("Hello, World! \n");
         
         return 0;
      }
      
    • 讲解

      1. 程序的第一行 #include <stdio.h> 是预处理器指令,告诉 C 编译器在实际编译之前要包含 stdio.h 文件。
      2. 下一行 int main() 是主函数,程序从这里开始执行。
      3. 下一行 // 将会被编译器忽略,这里放置程序的注释内容。它们被称为程序的注释。
      4. 下一行 printf(…) 是 C 中另一个可用的函数,会在屏幕上显示消息 “Hello, World!”。
      5. 下一行 return 0; 终止 main() 函数,并返回值 0。
  • 编译 & 执行 C 程序

    1. 打开一个文本编辑器,添加上述代码。
    2. 保存文件为 hello.c
    3. 打开命令提示符,进入到保存文件所在的目录。
    4. 键入 gcc hello.c,输入回车,编译代码。
    5. 如果代码中没有错误,命令提示符会跳到下一行,并生成 a.out 可执行文件。
    6. 现在,键入 a.out 来执行程序。
    7. 您可以看到屏幕上显示 “Hello World”

C 基本语法

  • C 的令牌(Token)

    C 程序由各种令牌组成,令牌可以是关键字、标识符、常量、字符串值,或者是一个符号。
    例如,下面的 C 语句包括五个令牌:、

    printf("Hello, World! \n");
    

    这五个令牌分别是:

    printf
    (
    "Hello, World! \n"
    )
    ;
    
  • 分号 ;

    在 C 程序中,分号是语句结束符。也就是说,每个语句必须以分号结束。它表明一个逻辑实体的结束。

  • 标识符

    • C 标识符是用来标识变量、函数,或任何其他用户自定义项目的名称。一个标识符以字母 A-Z 或 a-z 或下划线 _ 开始,后跟零个或多个字母、下划线和数字(0-9)。

    • C 标识符内不允许出现标点字符,比如 @、$ 和 %。C 是区分大小写的编程语言。因此,在 C 中,Manpowermanpower 是两个不同的标识符。

    • 下面列出几个有效的标识符:

      mohd       zara    abc   move_name  a_123
      myname50   _temp   j     a23b9      retVal
      
  • 关键字

    下表列出了 C 中的保留字。这些保留字不能作为常量名、变量名或其他标识符名称。

    关键字说明
    auto声明自动变量
    break跳出当前循环
    case开关语句分支
    char声明字符型变量或函数返回值类型
    const定义常量,如果一个变量被 const 修饰,那么它的值就不能再被改变
    continue结束当前循环,开始下一轮循环
    default开关语句中的"其它"分支
    do循环语句的循环体
    double声明双精度浮点型变量或函数返回值类型
    else条件语句否定分支(与 if 连用)
    enum声明枚举类型
    extern声明变量或函数是在其它文件或本文件的其他位置定义
    float声明浮点型变量或函数返回值类型
    for一种循环语句
    goto无条件跳转语句
    if条件语句
    int声明整型变量或函数
    long声明长整型变量或函数返回值类型
    register声明寄存器变量
    return子程序返回语句(可以带参数,也可不带参数)
    short声明短整型变量或函数
    signed声明有符号类型变量或函数
    sizeof计算数据类型或变量长度(即所占字节数)
    static声明静态变量
    struct声明结构体类型
    switch用于开关语句
    typedef用以给数据类型取别名
    unsigned声明无符号类型变量或函数
    union声明共用体类型
    void声明函数无返回值或无参数,声明无类型指针
    volatile说明变量在程序执行中可被隐含地改变
    while循环语句的循环条件

C数据类型

  • 在 C 语言中,数据类型指的是用于声明不同类型的变量或函数的一个广泛的系统。变量的类型决定了变量存储占用的空间,以及如何解释存储的位模式。

  • C 中的类型可分为以下几种:

    序号类型与描述
    1基本类型: 它们是算术类型,包括两种类型:整数类型和浮点类型。
    2枚举类型: 它们也是算术类型,被用来定义在程序中只能赋予其一定的离散整数值的变量。
    3void 类型: 类型说明符 void 表明没有可用的值。
    4派生类型: 它们包括:指针类型、数组类型、结构类型、共用体类型和函数类型。

​ 数组类型和结构类型统称为聚合类型。函数的类型指的是函数返回值的类型。

  • 整数类型

    类型存储大小值范围
    char1 字节-128 到 127 或 0 到 255
    unsigned char1 字节0 到 255
    signed char1 字节-128 到 127
    int2 或 4 字节-32,768 到 32,767 或 -2,147,483,648 到 2,147,483,647
    unsigned int2 或 4 字节0 到 65,535 或 0 到 4,294,967,295
    short2 字节-32,768 到 32,767
    unsigned short2 字节0 到 65,535
    long4 字节-2,147,483,648 到 2,147,483,647
    unsigned long4 字节0 到 4,294,967,295
    • 为了得到某个类型或某个变量在特定平台上的准确大小,您可以使用 sizeof 运算符。表达式 sizeof(type) 得到对象或类型的存储字节大小。

      #include "stdio.h"
      #include "limits.h"
      
      int main(){
          printf("int 存储大小: %lu \n",sizeof(int));
          return 0;
      }
      

    %lu 为 32 位无符号整数

  • 浮点类型

    类型存储大小值范围精度
    float4 字节1.2E-38 到 3.4E+386 位有效位
    double8 字节2.3E-308 到 1.7E+30815 位有效位
    long double16 字节3.4E-4932 到 1.1E+493219 位有效位
    • 头文件 float.h 定义了宏,在程序中可以使用这些值和其他有关实数二进制表示的细节。下面的实例将输出浮点类型占用的存储空间以及它的范围值:

      #include "stdio.h"
      #include "float.h"
      int main(){
          printf("float 存储最大字节数 :%lu \n",sizeof(float));
          printf("float的最小值:%E\n",FLT_MIN);
          printf("float的最大值:%E\n",FLT_MAX);
          printf("精度值:%d\n",FLT_DIG);
          return 0;
      }
      

      %E 为以指数形式输出单、双精度实数

  • void类型

    void 类型指定没有可用的值。它通常用于以下三种情况下

    序号类型与描述
    1函数返回为空
    C 中有各种函数都不返回值,或者您可以说它们返回空。不返回值的函数的返回类型为空。例如 void exit (int status);
    2函数参数为空
    C 中有各种函数不接受任何参数。不带参数的函数可以接受一个 void。例如 int rand(void);
    3指针指向 void
    类型为 void * 的指针代表对象的地址,而不是类型。例如,内存分配函数 void *malloc( size_t size ); 返回指向 void 的指针,可以转换为任何数据类型。

C变量

  • 变量其实只不过是程序可操作的存储区的名称。

  • C 中每个变量都有特定的类型,类型决定了变量存储的大小和布局,该范围内的值都可以存储在内存中,运算符可应用于变量上。

  • 变量的名称可以由字母、数字和下划线字符组成。它必须以字母或下划线开头。大写字母和小写字母是不同的,因为 C 是大小写敏感的。基于前一章讲解的基本类型,有以下几种基本的变量类型:

    image-20220525215042836

  • C 中的变量定义

    • 变量的声明

      变量定义就是告诉编译器在何处创建变量的存储,以及如何创建变量的存储。变量定义指定一个数据类型,并包含了该类型的一个或多个变量的列表,如下所示:

      type variable_list;
      

      在这里,type 必须是一个有效的 C 数据类型,可以是 char、w_char、int、float、double 或任何用户自定义的对象,variable_list 可以由一个或多个标识符名称组成,多个标识符之间用逗号分隔。下面列出几个有效的声明

      int    i, j, k;
      char   c, ch;
      float  f, salary;
      double d;
      

      int i, j, k; 声明并定义了变量 i、j 和 k,这指示编译器创建类型为 int 的名为 i、j、k 的变量。

    • 变量的初始化
      变量可以在声明的时候被初始化(指定一个初始值)。初始化器由一个等号,后跟一个常量表达式组成,如下所示:

      type variable_name = value;
      

      下面列举几个实例:

      extern int d = 3, f = 5;    // d 和 f 的声明与初始化
      int d = 3, f = 5;           // 定义并初始化 d 和 f
      byte z = 22;                // 定义并初始化 z
      char x = 'x';               // 变量 x 的值为 'x'
      
  • C 中的变量声明

    • 变量声明向编译器保证变量以指定的类型和名称存在,这样编译器在不需要知道变量完整细节的情况下也能继续进一步的编译。

    • 变量声明只在编译时有它的意义,在程序连接时编译器需要实际的变量声明。

    • 变量的声明有两种情况:

      1. 一种是需要建立存储空间的。例如:int a 在声明的时候就已经建立了存储空间。

      2. 另一种是不需要建立存储空间的,通过使用extern关键字声明变量名而不定义它。 例如:extern int a 其中变量 a 可以在别的文件中定义的。

      3. 除非有extern关键字,否则都是变量的定义。

        extern int i; //声明,不是定义
        int i; //声明,也是定义
        
    • 实例:

      #include <stdio.h>
       
      // 函数外定义变量 x 和 y
      int x;
      int y;
      int addtwonum()
      {
          // 函数内声明变量 x 和 y 为外部变量
          extern int x;
          extern int y;
          // 给外部变量(全局变量)x 和 y 赋值
          x = 1;
          y = 2;
          return x+y;
      }
       
      int main()
      {
          int result;
          // 调用函数 addtwonum
          result = addtwonum();
          
          printf("result 为: %d",result);//3
          return 0;
      }
      
    • 如果需要在一个源文件中引用另外一个源文件中定义的变量,我们只需在引用的文件中将变量加上 extern 关键字的声明即可

      • addtwonum.c 文件代码

        #include <stdio.h>
        /*外部变量声明*/
        extern int x ;
        extern int y ;
        int addtwonum()
        {
            return x+y;
        }
        
      • test.c 文件代码

        #include <stdio.h>
          
        /*定义两个全局变量*/
        int x=1;
        int y=2;
        int addtwonum();
        int main(void)
        {
            int result;
            result = addtwonum();
            printf("result 为: %d\n",result);//3
            return 0;
        }
        

C 常量

常量是固定值,在程序执行期间不会改变。这些固定的值,又叫做字面量。

常量可以是任何的基本数据类型,比如整数常量、浮点常量、字符常量,或字符串字面值,也有枚举常量。

常量就像是常规的变量,只不过常量的值在定义后不能进行修改。

  • 整数常量

    • 整数常量可以是十进制、八进制或十六进制的常量。
      前缀指定基数:0x 或 0X 表示十六进制,0 表示八进制,不带前缀则默认表示十进制。

    • 整数常量也可以带一个后缀,后缀是 U 和 L 的组合,U 表示无符号整数(unsigned),L 表示长整数(long)。后缀可以是大写,也可以是小写,U 和 L 的顺序任意。

    • 下面列举几个整数常量的实例:

      212         /* 合法的 */
      215u        /* 合法的 */
      0xFeeL      /* 合法的 */
      078         /* 非法的:8 不是八进制的数字 */
      032UU       /* 非法的:不能重复后缀 */
      
    • 以下是各种类型的整数常量的实例:

      85         /* 十进制 */
      0213       /* 八进制 */
      0x4b       /* 十六进制 */
      30         /* 整数 */
      30u        /* 无符号整数 */
      30l        /* 长整数 */
      30ul       /* 无符号长整数 */
      
  • 浮点常量

    • 浮点常量由整数部分、小数点、小数部分和指数部分组成。您可以使用小数形式或者指数形式来表示浮点常量。

    • 当使用小数形式表示时,必须包含整数部分、小数部分,或同时包含两者。当使用指数形式表示时, 必须包含小数点、指数,或同时包含两者。带符号的指数是用 e 或 E 引入的。

    • 下面列举几个浮点常量的实例

      3.14159       /* 合法的 */
      314159E-5L    /* 合法的 */
      510E          /* 非法的:不完整的指数 */
      210f          /* 非法的:没有小数或指数 */
      .e55          /* 非法的:缺少整数或分数 */
      
  • 字符常量

    • 字符常量是括在单引号中,例如,‘x’ 可以存储在 char 类型的简单变量中。

    • 字符常量可以是一个普通的字符(例如 ‘x’)、一个转义序列(例如 ‘\t’),或一个通用的字符(例如 ‘\u02C0’)。

    • 在 C 中,有一些特定的字符,当它们前面有反斜杠时,它们就具有特殊的含义,被用来表示如换行符(\n)或制表符(\t)等

      下表列出了一些这样的转义序列码:

      转义序列含义
      \\\ 字符
      \’’ 字符
      \"" 字符
      ?? 字符
      \a警报铃声
      \b退格键
      \f换页符
      \n换行符
      \r回车
      \t水平制表符
      \v垂直制表符
      \ooo一到三位的八进制数
      \xhh . . .一个或多个数字的十六进制数
  • 字符串常量

    • 字符串字面值或常量是括在双引号 “” 中的。一个字符串包含类似于字符常量的字符:普通的字符、转义序列和通用的字符。

    • 您可以使用空格做分隔符,把一个很长的字符串常量进行分行。

  • 定义常量

    • 在 C 中,有两种简单的定义常量的方式:

      1. 使用 #define 预处理器。

        下面是使用 #define 预处理器定义常量的形式:

        #define identifier value
        

        具体请看下面的实例:

        #include <stdio.h>
         
        #define LENGTH 10   
        #define WIDTH  5
        #define NEWLINE '\n'
         
        int main()
        {
         
           int area;  
          
           area = LENGTH * WIDTH;
           printf("value of area : %d", area);//50
           printf("%c", NEWLINE);
         
           return 0;
        }
        
      2. 使用 const 关键字。

        您可以使用 const 前缀声明指定类型的常量,如下所示:

        const type variable = value;
        

        const 声明常量要在一个语句内完成:

        img

C 存储类

存储类定义 C 程序中变量/函数的范围(可见性)和生命周期。这些说明符放置在它们所修饰的类型之前。下面列出 C 程序中可用的存储类:

  • auto
  • register
  • static
  • extern
  • auto 存储类

    auto 存储类是所有局部变量默认的存储类。

    {
       int mount;
       auto int month;
    }
    

    上面的实例定义了两个带有相同存储类的变量,auto 只能用在函数内,即 auto 只能修饰局部变量。

  • register 存储类

    register 存储类用于定义存储在寄存器中而不是 RAM 中的局部变量。这意味着变量的最大尺寸等于寄存器的大小(通常是一个字),且不能对它应用一元的 ‘&’ 运算符(因为它没有内存位置)。

    {
       register int  miles;
    }
    

    寄存器只用于需要快速访问的变量,比如计数器。还应注意的是,定义 ‘register’ 并不意味着变量将被存储在寄存器中,它意味着变量可能存储在寄存器中,这取决于硬件和实现的限制。

  • static 存储类

    • static 存储类指示编译器在程序的生命周期内保持局部变量的存在,而不需要在每次它进入和离开作用域时进行创建和销毁。因此,使用 static 修饰局部变量可以在函数调用之间保持局部变量的值。

    • static 修饰符也可以应用于全局变量。当 static 修饰全局变量时,会使变量的作用域限制在声明它的文件内。

    • 全局声明的一个 static 变量或方法可以被任何函数或方法调用,只要这些方法出现在跟 static 变量或方法同一个文件中。

    • 以下实例演示了 static 修饰全局变量和局部变量的应用:

      #include <stdio.h>
       
      /* 函数声明 */
      void func1(void);
       
      static int count=10;        /* 全局变量 - static 是默认的 */
       
      int main()
      {
        while (count--) {
            func1();
        }
        return 0;
      }
       
      void func1(void)
      {
      /* 'thingy' 是 'func1' 的局部变量 - 只初始化一次
       * 每次调用函数 'func1' 'thingy' 值不会被重置。
       */                
        static int thingy=5;
        thingy++;
        printf(" thingy 为 %d , count 为 %d\n", thingy, count);
      }
      

      结果

       thingy 为 6 , count 为 9
       thingy 为 7 , count 为 8
       thingy 为 8 , count 为 7
       thingy 为 9 , count 为 6
       thingy 为 10 , count 为 5
       thingy 为 11 , count 为 4
       thingy 为 12 , count 为 3
       thingy 为 13 , count 为 2
       thingy 为 14 , count 为 1
       thingy 为 15 , count 为 0
      
  • extern 存储类

    • extern 存储类用于提供一个全局变量的引用,全局变量对所有的程序文件都是可见的。当您使用 extern 时,对于无法初始化的变量,会把变量名指向一个之前定义过的存储位置

    • 当您有多个文件且定义了一个可以在其他文件中使用的全局变量或函数时,可以在其他文件中使用 extern 来得到已定义的变量或函数的引用。可以这么理解,extern 是用来在另一个文件中声明一个全局变量或函数

    • extern 修饰符通常用于当有两个或多个文件共享相同的全局变量或函数的时候,如下所示:

      第一个文件:main.c

      #include <stdio.h>
       
      int count ;
      extern void write_extern();
       
      int main()
      {
         count = 5;
         write_extern();
      }
      

      第二个文件:support.c

      #include <stdio.h>
       
      extern int count;
       
      void write_extern(void)
      {
         printf("count is %d\n", count);
      }
      

      在这里,第二个文件中的 extern 关键字用于声明已经在第一个文件 main.c 中定义的 count

C 函数

函数是一组一起执行一个任务的语句。每个 C 程序都至少有一个函数,即主函数 main() ,所有简单的程序都可以定义其他额外的函数。

您可以把代码划分到不同的函数中。如何划分代码到不同的函数中是由您来决定的,但在逻辑上,划分通常是根据每个函数执行一个特定的任务来进行的。

函数声明告诉编译器函数的名称、返回类型和参数。函数定义提供了函数的实际主体。

C 标准库提供了大量的程序可以调用的内置函数。例如,函数 strcat() 用来连接两个字符串,函数 memcpy() 用来复制内存到另一个位置。

  • 定义函数

    • C 语言中的函数定义的一般形式如下:

      return_type function_name( parameter list )
      {
         body of the function
      }
      

      在 C 语言中,函数由一个函数头和一个函数主体组成。下面列出一个函数的所有组成部分:

      • **返回类型:**一个函数可以返回一个值。return_type 是函数返回的值的数据类型。有些函数执行所需的操作而不返回值,在这种情况下,return_type 是关键字 void
      • **函数名称:**这是函数的实际名称。函数名和参数列表一起构成了函数签名。
      • **参数:**参数就像是占位符。当函数被调用时,您向参数传递一个值,这个值被称为实际参数。参数列表包括函数参数的类型、顺序、数量。参数是可选的,也就是说,函数可能不包含参数。
      • **函数主体:**函数主体包含一组定义函数执行任务的语句。
  • 函数声明

    函数声明会告诉编译器函数名称及如何调用函数。函数的实际主体可以单独定义。

    函数声明包括以下几个部分:

    return_type function_name( parameter list );
    
  • 调用函数

    • 创建 C 函数时,会定义函数做什么,然后通过调用函数来完成已定义的任务。
    • 当程序调用函数时,程序控制权会转移给被调用的函数。被调用的函数执行已定义的任务,当函数的返回语句被执行时,或到达函数的结束括号时,会把程序控制权交还给主程序。
    • 调用函数时,传递所需参数,如果函数返回一个值,则可以存储返回值。
  • 函数参数

    • 如果函数要使用参数,则必须声明接受参数值的变量。这些变量称为函数的形式参数。

    • 形式参数就像函数内的其他局部变量,在进入函数时被创建,退出函数时被销毁。

    • 当调用函数时,有两种向函数传递参数的方式:

      调用类型描述
      传值调用该方法把参数的实际值复制给函数的形式参数。在这种情况下,修改函数内的形式参数不会影响实际参数。
      引用调用通过指针传递方式,形参为指向实参地址的指针,当对形参的指向操作时,就相当于对实参本身进行的操作。

      默认情况下,C 使用传值调用来传递参数。一般来说,这意味着函数内的代码不能改变用于调用函数的实际参数。

C 作用域规则

任何一种编程中,作用域是程序中定义的变量所存在的区域,超过该区域变量就不能被访问。C 语言中有三个地方可以声明变量:

  1. 在函数或块内部的局部变量
  2. 在所有函数外部的全局变量
  3. 形式参数的函数参数定义中

让我们来看看什么是局部变量、全局变量和形式参数。

  • 局部变量

    • 在某个函数或块的内部声明的变量称为局部变量。
    • 它们只能被该函数或该代码块内部的语句使用。
    • 局部变量在函数外部是不可知的。
  • 全局变量

    • 全局变量是定义在函数外部,通常是在程序的顶部。全局变量在整个程序生命周期内都是有效的,在任意的函数内部能访问全局变量。
    • 全局变量可以被任何函数访问。也就是说,全局变量在声明后整个程序中都是可用的
  • 形式参数

    函数的参数,形式参数,被当作该函数内的局部变量,如果与全局变量同名它们会优先使用。

  • 全局变量与局部变量在内存中的区别:

    • 全局变量保存在内存的全局存储区中,占用静态的存储单元;
    • 局部变量保存在栈中,只有在所在函数被调用时才动态地为变量分配存储单元。
  • 初始化局部变量和全局变量

    • 当局部变量被定义时,系统不会对其初始化,您必须自行对其初始化。

    • 定义全局变量时,系统会自动对其初始化,如下所示:

      数据类型初始化默认值
      int0
      char‘\0’
      float0
      double0
      pointerNULL

C 数组

C 语言支持数组数据结构,它可以存储一个固定大小的相同类型元素的顺序集合。数组是用来存储一系列数据,但它往往被认为是一系列相同类型的变量。

所有的数组都是由连续的内存位置组成。最低的地址对应第一个元素,最高的地址对应最后一个元素。

  • 声明数组

    在 C 中要声明一个数组,需要指定元素的类型和元素的数量,如下所示:

    type arrayName [ arraySize ];
    
  • 初始化数组

    • 在 C 中,您可以逐个初始化数组,也可以使用一个初始化语句,如下所示:

      double balance[5] = {1000.0, 2.0, 3.4, 7.0, 50.0};
      

      大括号 { } 之间的值的数目不能大于我们在数组声明时在方括号 [ ] 中指定的元素数目。

    • 如果您省略掉了数组的大小,数组的大小则为初始化时元素的个数。

      double balance[] = {1000.0, 2.0, 3.4, 7.0, 50.0};
      

C enum(枚举)

  • 简介

    • 枚举是 C 语言中的一种基本数据类型,它可以让数据更简洁,更易读。

    • 枚举语法定义格式为:

      enum 枚举名 {枚举元素1,枚举元素2,……};
      
    • 接下来我们举个例子,比如:一星期有 7 天,如果不用枚举,我们需要使用 #define 来为每个整数定义一个别名:

      #define MON  1
      #define TUE  2
      #define WED  3
      #define THU  4
      #define FRI  5
      #define SAT  6
      #define SUN  7
      

      这个看起来代码量就比较多,接下来我们看看使用枚举的方式:

      enum DAY
      {
            MON=1, TUE, WED, THU, FRI, SAT, SUN
      };
      

      **注意:**第一个枚举成员的默认值为整型的 0,后续枚举成员的值在前一个成员上加 1。我们在这个实例中把第一个枚举成员的值定义为 1,第二个就为 2,以此类推。

      image-20220703152435077

    • 枚举变量的定义

      1. 先定义枚举类型,再定义枚举变量

        enum DAY
        {
              MON=1, TUE, WED, THU, FRI, SAT, SUN
        };
        enum DAY day;
        
      2. 定义枚举类型的同时定义枚举变量

        enum DAY
        {
              MON=1, TUE, WED, THU, FRI, SAT, SUN
        } day;
        
      3. 省略枚举名称,直接定义枚举变量

        enum
        {
              MON=1, TUE, WED, THU, FRI, SAT, SUN
        } day;
        
    • 在C 语言中,枚举类型是被当做 int 或者 unsigned int 类型来处理的,所以按照 C 语言规范是没有办法遍历枚举类型的。不过在一些特殊的情况下,枚举类型必须连续是可以实现有条件的遍历。

      #include <stdio.h>
       
      enum DAY
      {
            MON=1, TUE, WED, THU, FRI, SAT, SUN
      } day;
      int main()
      {
          // 遍历枚举元素
          for (day = MON; day <= SUN; day++) {
              printf("枚举元素:%d \n", day);
          }
      }
      

      以下枚举类型不连续,这种枚举无法遍历

      enum
      {
          ENUM_0,
          ENUM_10 = 10,
          ENUM_11
      };
      

C 指针

  • 每一个变量都有一个内存位置,每一个内存位置都定义了可使用 & 运算符访问的地址,它表示了在内存中的一个地址。请看下面的实例,它将输出定义的变量地址:

    #include <stdio.h>
     
    int main ()
    {
        int var_runoob = 10;
        int *p;              // 定义指针变量
        p = &var_runoob;
     
       printf("var_runoob 变量的地址: %p\n", p);//var_runoob 变量的地址: 0x7ffeeaae08d8
       return 0;
    }
    

    img

  • 什么是指针?

    • 指针也就是内存地址,指针变量是用来存放内存地址的变量。就像其他变量或常量一样,您必须在使用指针存储其他变量地址之前,对其进行声明。指针变量声明的一般形式为:

      type *var_name;
      
    • 在这里,type 是指针的基类型,它必须是一个有效的 C 数据类型,var_name 是指针变量的名称。用来声明指针的星号 * 与乘法中使用的星号是相同的。但是,在这个语句中,星号是用来指定一个变量是指针。以下是有效的指针声明:

      int    *ip;    /* 一个整型的指针 */
      double *dp;    /* 一个 double 型的指针 */
      float  *fp;    /* 一个浮点型的指针 */
      char   *ch;    /* 一个字符型的指针 */
      
    • 所有实际数据类型,不管是整型、浮点型、字符型,还是其他的数据类型,对应指针的值的类型都是一样的,都是一个代表内存地址的长的十六进制数。

      不同数据类型的指针之间唯一的不同是,指针所指向的变量或常量的数据类型不同。

  • 如何使用指针?

    使用指针时会频繁进行以下几个操作:定义一个指针变量、把变量地址赋值给指针、访问指针变量中可用地址的值。这些是通过使用一元运算符 ***** 来返回位于操作数所指定地址的变量的值。下面的实例涉及到了这些操作:

    #include <stdio.h>
     
    int main ()
    {
       int  var = 20;   /* 实际变量的声明 */
       int  *ip;        /* 指针变量的声明 */
     
       ip = &var;  /* 在指针变量中存储 var 的地址 */
     
       printf("var 变量的地址: %p\n", &var  );
     
       /* 在指针变量中存储的地址 */
       printf("ip 变量存储的地址: %p\n", ip );
     
       /* 使用指针访问值 */
       printf("*ip 变量的值: %d\n", *ip );
     
       return 0;
    }
    

    结果:

    var 变量的地址: 0x7ffeeef168d8
    ip 变量存储的地址: 0x7ffeeef168d8
    *ip 变量的值: 20
    
  • C 中的 NULL 指针

    • 在变量声明的时候,如果没有确切的地址可以赋值,为指针变量赋一个 NULL 值是一个良好的编程习惯。赋为 NULL 值的指针被称为空指针。NULL 指针是一个定义在标准库中的值为零的常量。请看下面的程序:

      #include <stdio.h>
       
      int main ()
      {
         int  *ptr = NULL;
       
         printf("ptr 的地址是 %p\n", ptr  );//ptr 的地址是 0x0
       
         return 0;
      }
      
    • 在大多数的操作系统上,程序不允许访问地址为 0 的内存,因为该内存是操作系统保留的。然而,内存地址 0 有特别重要的意义,它表明该指针不指向一个可访问的内存位置。但按照惯例,如果指针包含空值(零值),则假定它不指向任何东西。如需检查一个空指针,您可以使用 if 语句,如下所示:

      if(ptr)     /* 如果 p 非空,则完成 */
      if(!ptr)    /* 如果 p 为空,则完成 */
      

C 函数指针和回调函数

函数指针

  • 函数指针是指向函数的指针变量。

  • 通常我们说的指针变量是指向一个整型、字符型或数组等变量,而函数指针是指向函数。

  • 函数指针可以像一般函数一样,用于调用函数、传递参数。

  • 函数指针变量的声明

    typedef int (*fun_ptr)(int,int); // 声明一个指向同样参数、返回值的函数指针类型
    
  • 以下实例声明了函数指针变量 p,指向函数 max:

    #include <stdio.h>
     
    int max(int x, int y)
    {
        return x > y ? x : y;
    }
     
    int main(void)
    {
        /* p 是函数指针 */
        int (* p)(int, int) = & max; // &可以省略
        int a, b, c, d;
     
        printf("请输入三个数字:");
        scanf("%d %d %d", & a, & b, & c);
     
        /* 与直接调用函数等价,d = max(max(a, b), c) */
        d = p(p(a, b), c); 
     
        printf("最大的数字是: %d\n", d);
     
        return 0;
    }
    

回调函数

  • 函数指针作为某个函数的参数

  • 函数指针变量可以作为某个函数的参数来使用的,回调函数就是一个通过函数指针调用的函数。

    简单讲:回调函数是由别人的函数执行时调用你实现的函数。

  • 实例

    实例中 populate_array 函数定义了三个参数,其中第三个参数是函数的指针,通过该函数来设置数组的值。

    实例中我们定义了回调函数 getNextRandomValue,它返回一个随机值,它作为一个函数指针传递给 populate_array 函数。

    populate_array 将调用 10 次回调函数,并将回调函数的返回值赋值给数组。

    #include <stdlib.h>  
    #include <stdio.h>
     
    // 回调函数
    void populate_array(int *array, size_t arraySize, int (*getNextValue)(void))
    {
        for (size_t i=0; i<arraySize; i++)
            array[i] = getNextValue();
    }
     
    // 获取随机值
    int getNextRandomValue(void)
    {
        return rand();
    }
     
    int main(void)
    {
        int myarray[10];
        /* getNextRandomValue 不能加括号,否则无法编译,因为加上括号之后相当于传入此参数时传入了 int , 而不是函数指针*/
        populate_array(myarray, 10, getNextRandomValue);
        for(int i = 0; i < 10; i++) {
            printf("%d ", myarray[i]);
        }
        printf("\n");
        return 0;
    }
    

C 字符串

  • 在 C 语言中,字符串实际上是使用空字符 \0 结尾的一维字符数组。因此,\0 是用于标记字符串的结束。

  • 空字符(Null character)又称结束符,缩写 NUL,是一个数值为 0 的控制字符,\0 是转义字符,意思是告诉编译器,这不是字符 0,而是空字符。

  • C 中有大量操作字符串的函数:

    序号函数 & 目的
    1strcpy(s1, s2); 复制字符串 s2 到字符串 s1。
    2strcat(s1, s2); 连接字符串 s2 到字符串 s1 的末尾。
    3strlen(s1); 返回字符串 s1 的长度。
    4strcmp(s1, s2); 如果 s1 和 s2 是相同的,则返回 0;如果 s1<s2 则返回小于 0;如果 s1>s2 则返回大于 0。
    5strchr(s1, ch); 返回一个指针,指向字符串 s1 中字符 ch 的第一次出现的位置。
    6strstr(s1, s2); 返回一个指针,指向字符串 s1 中字符串 s2 的第一次出现的位置。

C 结构体

数组允许定义可存储相同类型数据项的变量;
结构是 C 编程中另一种用户自定义的可用的数据类型,它允许您存储不同类型的数据项。

结构用于表示一条记录,假设您想要跟踪图书馆中书本的动态,您可能需要跟踪每本书的下列属性:

  • Title
  • Author
  • Subject
  • Book ID
  • 定义结构

    为了定义结构,您必须使用 struct 语句。struct 语句定义了一个包含多个成员的新的数据类型,struct 语句的格式如下:

    struct tag { 
        member-list
        member-list 
        member-list  
        ...
    } variable-list ;
    

    tag 是结构体标签。

    member-list 是标准的变量定义,比如 int i; 或者 float f,或者其他有效的变量定义。

    variable-list 结构变量,定义在结构的末尾,最后一个分号之前,您可以指定一个或多个结构变量。

    下面是声明 Book 结构的方式:

    struct Books
    {
       char  title[50];
       char  author[50];
       char  subject[100];
       int   book_id;
    } book;
    

    在一般情况下,tag、member-list、variable-list 这 3 部分至少要出现 2 个。以下为实例:

    //此声明声明了拥有3个成员的结构体,分别为整型的a,字符型的b和双精度的c
    //同时又声明了结构体变量s1
    //这个结构体并没有标明其标签
    struct 
    {
        int a;
        char b;
        double c;
    } s1;
     
    //此声明声明了拥有3个成员的结构体,分别为整型的a,字符型的b和双精度的c
    //结构体的标签被命名为SIMPLE,没有声明变量
    struct SIMPLE
    {
        int a;
        char b;
        double c;
    };
    //用SIMPLE标签的结构体,另外声明了变量t1、t2、t3
    struct SIMPLE t1, t2[20], *t3;
     
    //也可以用typedef创建新类型
    typedef struct
    {
        int a;
        char b;
        double c; 
    } Simple2;
    //现在可以用Simple2作为类型声明新的结构体变量
    Simple2 u1, u2[20], *u3;
    

    结构体的成员可以包含其他结构体,也可以包含指向自己结构体类型的指针,而通常这种指针的应用是为了实现一些更高级的数据结构如链表和树等。

    //此结构体的声明包含了其他的结构体
    struct COMPLEX
    {
        char string[100];
        struct SIMPLE a;
    };
     
    //此结构体的声明包含了指向自己类型的指针
    struct NODE
    {
        char string[100];
        struct NODE *next_node;
    };
    
  • 结构体变量的初始化

    和其它类型变量一样,对结构体变量可以在定义时指定初始值。

    #include <stdio.h>
     
    struct Books
    {
       char  title[50];
       char  author[50];
       char  subject[100];
       int   book_id;
    } book = {"C 语言", "RUNOOB", "编程语言", 123456};
     
    int main()
    {
        printf("title : %s\nauthor: %s\nsubject: %s\nbook_id: %d\n", book.title, book.author, book.subject, book.book_id);
    }
    

    结果:

    title : C 语言
    author: RUNOOB
    subject: 编程语言
    book_id: 123456
    
  • 访问结构成员

    • 为了访问结构的成员,我们使用成员访问运算符(.)

    • 成员访问运算符是结构变量名称和我们要访问的结构成员之间的一个句号。您可以使用 struct 关键字来定义结构类型的变量。

    • 下面的实例演示了结构的用法:

      #include <stdio.h>
      #include <string.h>
       
      struct Books
      {
         char  title[50];
         char  author[50];
         char  subject[100];
         int   book_id;
      };
       
      int main( )
      {
         struct Books Book1;        /* 声明 Book1,类型为 Books */
         struct Books Book2;        /* 声明 Book2,类型为 Books */
       
         /* Book1 详述 */
         strcpy( Book1.title, "C Programming");
         strcpy( Book1.author, "Nuha Ali"); 
         strcpy( Book1.subject, "C Programming Tutorial");
         Book1.book_id = 6495407;
       
         /* Book2 详述 */
         strcpy( Book2.title, "Telecom Billing");
         strcpy( Book2.author, "Zara Ali");
         strcpy( Book2.subject, "Telecom Billing Tutorial");
         Book2.book_id = 6495700;
       
         /* 输出 Book1 信息 */
         printf( "Book 1 title : %s\n", Book1.title);
         printf( "Book 1 author : %s\n", Book1.author);
         printf( "Book 1 subject : %s\n", Book1.subject);
         printf( "Book 1 book_id : %d\n", Book1.book_id);
       
         /* 输出 Book2 信息 */
         printf( "Book 2 title : %s\n", Book2.title);
         printf( "Book 2 author : %s\n", Book2.author);
         printf( "Book 2 subject : %s\n", Book2.subject);
         printf( "Book 2 book_id : %d\n", Book2.book_id);
       
         return 0;
      }
      
  • 结构作为函数参数

    您可以把结构作为函数参数,传参方式与其他类型的变量或指针类似。您可以使用上面实例中的方式来访问结构变量:

    #include <stdio.h>
    #include <string.h>
     
    struct Books
    {
       char  title[50];
       char  author[50];
       char  subject[100];
       int   book_id;
    };
     
    /* 函数声明 */
    void printBook( struct Books book );
    int main( )
    {
       struct Books Book1;        /* 声明 Book1,类型为 Books */
       struct Books Book2;        /* 声明 Book2,类型为 Books */
     
       /* Book1 详述 */
       strcpy( Book1.title, "C Programming");
       strcpy( Book1.author, "Nuha Ali"); 
       strcpy( Book1.subject, "C Programming Tutorial");
       Book1.book_id = 6495407;
     
       /* Book2 详述 */
       strcpy( Book2.title, "Telecom Billing");
       strcpy( Book2.author, "Zara Ali");
       strcpy( Book2.subject, "Telecom Billing Tutorial");
       Book2.book_id = 6495700;
     
       /* 输出 Book1 信息 */
       printBook( Book1 );
     
       /* 输出 Book2 信息 */
       printBook( Book2 );
     
       return 0;
    }
    void printBook( struct Books book )
    {
       printf( "Book title : %s\n", book.title);
       printf( "Book author : %s\n", book.author);
       printf( "Book subject : %s\n", book.subject);
       printf( "Book book_id : %d\n", book.book_id);
    }
    
  • 指向结构的指针

    您可以定义指向结构的指针,方式与定义指向其他类型变量的指针相似,如下所示:

    struct Books *struct_pointer;
    

    现在,您可以在上述定义的指针变量中存储结构变量的地址。为了查找结构变量的地址,请把 & 运算符放在结构名称的前面,如下所示:

    struct_pointer = &Book1;
    

    为了使用指向该结构的指针访问结构的成员,您必须使用 -> 运算符,如下所示:

    struct_pointer->title;
    

    让我们使用结构指针来重写上面的实例,这将有助于您理解结构指针的概念:

    #include <stdio.h>
    #include <string.h>
     
    struct Books
    {
       char  title[50];
       char  author[50];
       char  subject[100];
       int   book_id;
    };
     
    /* 函数声明 */
    void printBook( struct Books *book );
    int main( )
    {
       struct Books Book1;        /* 声明 Book1,类型为 Books */
       struct Books Book2;        /* 声明 Book2,类型为 Books */
     
       /* Book1 详述 */
       strcpy( Book1.title, "C Programming");
       strcpy( Book1.author, "Nuha Ali"); 
       strcpy( Book1.subject, "C Programming Tutorial");
       Book1.book_id = 6495407;
     
       /* Book2 详述 */
       strcpy( Book2.title, "Telecom Billing");
       strcpy( Book2.author, "Zara Ali");
       strcpy( Book2.subject, "Telecom Billing Tutorial");
       Book2.book_id = 6495700;
     
       /* 通过传 Book1 的地址来输出 Book1 信息 */
       printBook( &Book1 );
     
       /* 通过传 Book2 的地址来输出 Book2 信息 */
       printBook( &Book2 );
     
       return 0;
    }
    void printBook( struct Books *book )
    {
       printf( "Book title : %s\n", book->title);
       printf( "Book author : %s\n", book->author);
       printf( "Book subject : %s\n", book->subject);
       printf( "Book book_id : %d\n", book->book_id);
    }
    

C 共用体

共用体是一种特殊的数据类型,允许您在相同的内存位置存储不同的数据类型。您可以定义一个带有多成员的共用体,但是任何时候只能有一个成员带有值。共用体提供了一种使用相同的内存位置的有效方式。

  • 定义共用体

    为了定义共用体,您必须使用 union 语句,方式与定义结构类似。union 语句定义了一个新的数据类型,带有多个成员。union 语句的格式如下:

    union [union tag]
    {
       member definition;
       member definition;
       ...
       member definition;
    } [one or more union variables];
    

    union tag 是可选的,每个 member definition 是标准的变量定义,比如 int i; 或者 float f; 或者其他有效的变量定义。在共用体定义的末尾,最后一个分号之前,您可以指定一个或多个共用体变量,这是可选的。下面定义一个名为 Data 的共用体类型,有三个成员 i、f 和 str:

    union Data
    {
       int i;
       float f;
       char  str[20];
    } data;
    

    现在,Data 类型的变量可以存储一个整数、一个浮点数,或者一个字符串。这意味着一个变量(相同的内存位置)可以存储多个多种类型的数据。您可以根据需要在一个共用体内使用任何内置的或者用户自定义的数据类型。

    共用体占用的内存应足够存储共用体中最大的成员。例如,在上面的实例中,Data 将占用 20 个字节的内存空间,因为在各个成员中,字符串所占用的空间是最大的。下面的实例将显示上面的共用体占用的总内存大小:

    #include <stdio.h>
    #include <string.h>
     
    union Data
    {
       int i;
       float f;
       char  str[20];
    };
     
    int main( )
    {
       union Data data;        
     
       printf( "Memory size occupied by data : %d\n", sizeof(data));
     //Memory size occupied by data : 20
       return 0;
    }
    
  • 访问共用体成员

    为了访问共用体的成员,我们使用成员访问运算符(.)。成员访问运算符是共用体变量名称和我们要访问的共用体成员之间的一个句号。您可以使用 union 关键字来定义共用体类型的变量。下面的实例演示了共用体的用法:

    #include <stdio.h>
    #include <string.h>
     
    union Data
    {
       int i;
       float f;
       char  str[20];
    };
     
    int main( )
    {
       union Data data;        
     
       data.i = 10;
       data.f = 220.5;
       strcpy( data.str, "C Programming");
     
       printf( "data.i : %d\n", data.i);
       printf( "data.f : %f\n", data.f);
       printf( "data.str : %s\n", data.str);
     
       return 0;
    }
    

    当上面的代码被编译和执行时,它会产生下列结果:

    data.i : 1917853763
    data.f : 4122360580327794860452759994368.000000
    data.str : C Programming
    

    在这里,我们可以看到共用体的 if 成员的值有损坏,因为最后赋给变量的值占用了内存位置,这也是 str 成员能够完好输出的原因。现在让我们再来看一个相同的实例,这次我们在同一时间只使用一个变量,这也演示了使用共用体的主要目的:

    #include <stdio.h>
    #include <string.h>
     
    union Data
    {
       int i;
       float f;
       char  str[20];
    };
     
    int main( )
    {
       union Data data;        
     
       data.i = 10;
       printf( "data.i : %d\n", data.i);
       
       data.f = 220.5;
       printf( "data.f : %f\n", data.f);
       
       strcpy( data.str, "C Programming");
       printf( "data.str : %s\n", data.str);
     
       return 0;
    }
    

    当上面的代码被编译和执行时,它会产生下列结果:

    data.i : 10
    data.f : 220.500000
    data.str : C Programming
    

    在这里,所有的成员都能完好输出,因为同一时间只用到一个成员。

C typedef

  • C 语言提供了 typedef 关键字,您可以使用它来为类型取一个新的名字。下面的实例为单字节数字定义了一个术语 BYTE

    typedef unsigned char BYTE;
    

    在这个类型定义之后,标识符 BYTE 可作为类型 unsigned char 的缩写

  • 您也可以使用 typedef 来为用户自定义的数据类型取一个新的名字。例如,您可以对结构体使用 typedef 来定义一个新的数据类型名字,然后使用这个新的数据类型来直接定义结构变量,如下:

    #include <stdio.h>
    #include <string.h>
     
    typedef struct Books
    {
       char  title[50];
       char  author[50];
       char  subject[100];
       int   book_id;
    } Book;
     
    int main( )
    {
       Book book;
     
       strcpy( book.title, "C 教程");
       strcpy( book.author, "Runoob"); 
       strcpy( book.subject, "编程语言");
       book.book_id = 12345;
     
       printf( "书标题 : %s\n", book.title);
       printf( "书作者 : %s\n", book.author);
       printf( "书类目 : %s\n", book.subject);
       printf( "书 ID : %d\n", book.book_id);
     
       return 0;
    }
    
  • typedef vs #define

    #define 是 C 指令,用于为各种数据类型定义别名,与 typedef 类似,但是它们有以下几点不同:

    • typedef 仅限于为类型定义符号名称,#define 不仅可以为类型定义别名,也能为数值定义别名,比如您可以定义 1 为 ONE。

      #include <stdio.h>
       
      #define TRUE  1
      #define FALSE 0
       
      int main( )
      {
         printf( "TRUE 的值: %d\n", TRUE);
         printf( "FALSE 的值: %d\n", FALSE);
       
         return 0;
      }
      
    • typedef 是由编译器执行解释的,#define 语句是由预编译器进行处理的。

C 输入 & 输出

当我们提到输入时,这意味着要向程序填充一些数据。输入可以是以文件的形式或从命令行中进行。C 语言提供了一系列内置的函数来读取给定的输入,并根据需要填充到程序中。

当我们提到输出时,这意味着要在屏幕上、打印机上或任意文件中显示一些数据。C 语言提供了一系列内置的函数来输出数据到计算机屏幕上和保存数据到文本文件或二进制文件中。

  • 标准文件

    C 语言把所有的设备都当作文件。所以设备(比如显示器)被处理的方式与文件相同。以下三个文件会在程序执行时自动打开,以便访问键盘和屏幕。

    标准文件文件指针设备
    标准输入stdin键盘
    标准输出stdout屏幕
    标准错误stderr您的屏幕

    C 语言中的 I/O (输入/输出) 通常使用 printf() 和 scanf() 两个函数。

    scanf() 函数用于从标准输入(键盘)读取并格式化, printf() 函数发送格式化输出到标准输出(屏幕)。

  • 要点:

    • 所有的 C 语言程序都需要包含 main() 函数。 代码从 main() 函数开始执行。
    • printf() 用于格式化输出到屏幕。printf() 函数在 “stdio.h” 头文件中声明。
    • stdio.h 是一个头文件 (标准输入输出头文件) and #include 是一个预处理命令,用来引入头文件。 当编译器遇到 printf() 函数时,如果没有找到 stdio.h 头文件,会发生编译错误。
    • return 0; 语句用于表示退出程序。
  • getchar() & putchar() 函数

    int getchar(void) 函数从屏幕读取下一个可用的字符,并把它返回为一个整数。这个函数在同一个时间内只会读取一个单一的字符。您可以在循环内使用这个方法,以便从屏幕上读取多个字符。

    int putchar(int c) 函数把字符输出到屏幕上,并返回相同的字符。这个函数在同一个时间内只会输出一个单一的字符。您可以在循环内使用这个方法,以便在屏幕上输出多个字符。

  • gets() & puts() 函数

    char *gets(char *s) 函数从 stdin 读取一行到 s 所指向的缓冲区,直到一个终止符或 EOF。

    int puts(const char *s) 函数把字符串 s 和一个尾随的换行符写入到 stdout

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值