【C语言篇】☞ 16. 标准函数、预处理

C语言标准函数

1. 堆内存管理

  • malloc函数(动态内存分配):在堆中分配指定大小的一段连续的内存空间,返回这片内存的首地址。(分配内存空间)

    返回类型是 void* 类型,void* 表示未确定类型的指针。C,C++规定,void* 类型可以强制转换为任何其它类型的指针。

   (提示:在C中void*可以不用强制转换,但在C++中一定要强转,否则编译不通过报错;便于程序能移植到C++中,建议养成强制转换的习惯)

  

    

  • calloc函数:与malloc作用相同,只是默认会把分配到的所有字节都清零。(分配内存空间 + 初始化清零)

    calloc()函数有两个参数,分别为元素的数目和每个元素的大小,这两个参数的乘积就是要分配的内存空间的大小。

    

  • realloc函数:更改由malloc()函数分配的内存空间的大小。并将新的内存指针返回。
    • 如果将分配的内存减少,realloc仅仅是改变索引的信息。
    • 如果是将分配的内存扩大,则有以下情况:
      • 如果当前内存段后面有需要的内存空间,则直接扩展这段内存空间,realloc()将返回原指针。

      • 如果当前内存段后面的空闲字节不够,那么就使用堆中的第一个能够满足这一要求的内存块,将目前的数据复制到新的位置,并将原来的数据块释放掉,返回新的内存块位置。 
      • 如果申请失败,将返回NULL,此时,原来的指针仍然有效。可以使用realloc函数对用malloc函数分配好的空间重新分配,一般是扩大。

    • 注意:如果调用成功,不管当前内存段后面的空闲空间是否满足要求,都会释放掉原来的指针,重新返回一个指针,虽然返回的指针有可能和原来的指针一样,即不能再次释放掉原来的指针。

     

  • free函数:释放内存空间

    free(p); //释放指针p所指的内存空间

2. 标准输入输出

(1)控制台输入输出,可以接收用户从键盘上输入的数据

  • scanf()在输入字符的时候存在缓冲区问题

    通过scanf"%*c";清除缓冲区。

  • scanf()和gets()在输入字符串的时候不存在缓冲区问题,但存在安全性问题(内存溢出)  
  • fgets()函数,解决安全性问题
    • 语法格式:fgets(参数1,参数2,参数3);
      • 参数1:保存数据的首位置
      • 参数2:保存的长度(包括结束符)
      • 参数3stdin(标准控制台输入)

(2)格式化输入输出

  • printf()可以输出字符串,并且可以根据占位符的个数来决定输出字符串的个数。
  • puts()可以输出一个字符串,而且是自动换行。

  • printf()与puts

    • 相同点:都可以输出字符串

    • 不同点:

      • printf()需要手动换行,可以多次输出字符

      • puts()自动换行,只能输出一次字符串内容

  • const关键字:可以将变量变为只读,只可以在初始化时改变变量的值,此变量就为常量。
    • const int*p = &i; //指针指向的值变为只读
    • int *const p = &i; //指针的值变为只读

(3)数据类型之间的转换

  • sprintf函数,可以将各种数据类型(整型、长整型、浮点型等)转换为字符串。
  • 将字符串转换为任意类型(整型、长整型、浮点型等)。

    • atof():将字符串转换为双精度浮点型值。
    • atoi():将字符串转换为整型值。

    • atol():将字符串转换为长整型值。

   

3. 其它库函数

(1)可变长参数

   

(2)日期和时间处理(time.h

  • 时间处理函数

    clock函数

    difftime函数

    mktime函数

    time函数

  • 时间转换函数

    asctime函数

    ctime函数

    gmtime函数

    localtime函数

(3)内存清理与拷贝(string.h

   

  

预处理

1. 预处理器

  预处理器是一个程序,用来处理源程序中的预处理指令,一个源程序在编译前要先做预处理。

  预处理:是将源程序中的预处理指令进行替换和处理。程序代码在提交给编译器之前,先将一些代码替换(预处理)

  命令:gcc(clang) -E xxx.c //(-E)只做预处理

2. 预处理指令

  预处理指令:以"#"开头的指令都是预处理指令。

  如:#include, #define, 条件编译指令(#if, #ifdef, #ifndef, #endif...)

  (可以出现在任何源程序位置,但必须一行结束,一条指令只能是一行。一行如果写不完,就用""换行)

(1)文件包含:#include <> #include "" : 将一个文件中的内容复制到当前位置

#include在干什么找到一个文件,将文件中的内容全部拷贝到此。是预处理指令,由预处理器来处理的

#include <stdio.h> #include " "

<>的意思是从系统指定的位置查找文件。stdio.h是系统标准的头文件,保存在系统指定的位置,所以用<>

“” 从当前目录查找文件,如果在当前目录下找不着,就到系统指定的目录下找

(2)宏定义:#define 用来定义宏,宏是一种代码替换技术。

   无参宏定义(简单的宏):只做简单的替换,提高程序的可读性和可维护性

   #define PI 3.1415926 //定义了一个宏,名字是PI 用于替换3.14

   

  

  

  

    

    

(3)条件编译指令(#if, #ifdef, #ifndef, #endif, #elif, #else, #undef, #defined, #error)

条件编译指令将决定哪些代码被编译,而哪些是不被编译的。

在代码中设置编译条件,根据编译条件进行代码的编译并运行。(跨平台)

在编译文件的时候传入一个参数,根据参数就可以对代码进行有选择的编译。

    

    #ifdef 和 #ifndef  这二者主要用于防止头文件重复包含。

    #if defined 等价于 #ifdef;  #if !defined 等价于 #ifndef

     

     

原文地址:https://www.cnblogs.com/bossren/p/6422230.html