zoukankan      html  css  js  c++  java
  • 【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

         

         

  • 相关阅读:
    关于spring security的若干事情
    .net2005 datagridview 如何获取值改变的单元格的集合??(小弟没有为datagridview添加数据源,也就是说单元格中的数据是手工录入的)
    关于做一个通用打印类的设想,大家谈谈看法
    请教C#,两个类中的变量互访问题
    刚发现了一个问题,关于vs2005 datagridview的,我发现在设计行标头的HeaderCell.Value的时候要是设置RowTemplate.Height 的值>= 17则行标头的那个黑三角就显示出来了,要是小于17就不能显示了,想问问大家,是怎么回事?
    软件架构模式基本概念及三者区别
    以英雄联盟的方式建模,谈对依赖注入(DI)的理解以及Autofac的用法(一)
    适配器模式
    [翻译] WCF运行时架构
    关于synchronized 影响可见性的问题
  • 原文地址:https://www.cnblogs.com/bossren/p/6422230.html
Copyright © 2011-2022 走看看