无处不在的C

  • qsort排序

    void qsort(void *base, size_t nitems, size_t size, int (*compar)(const void *, const void *))

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    #include <stdio.h>
    #include <stdlib.h>

    int values[] = { 88, 56, 100, 2, 25 };

    int cmpfunc (const void * a, const void * b)
    {
    return ( *(int*)a - *(int*)b );
    }

    int main()
    {
    int n;

    printf("排序之前的列表:\n");
    for( n = 0 ; n < 5; n++ ) {
    printf("%d ", values[n]);
    }

    qsort(values, 5, sizeof(int), cmpfunc);

    printf("\n排序之后的列表:\n");
    for( n = 0 ; n < 5; n++ ) {
    printf("%d ", values[n]);
    }

    return(0);
    }
  • rand随机数

    先srand设置种子,再获取 srand((unsigned)time(NULL));

  • 宏定义

    没有特殊语义, 直接程序内部替换
    #define N 100 字符串替换
    #define M (n*n+3*n) 代码块替换
    #define M(y) y*y+3*y //带参数宏定义,调用 M(5)
    #define STR(s) #s 一个#表示把参数s转换成”xxx”字符串形式
    #define CON(a, b) a##e##b 两个##表示连接操作,CON(2,3)–> 2e3
    预定义宏,无需声明可以直接使用的:

  • __LINE__:表示当前源代码的行号;
  • __FILE__:表示当前源文件的名称;
  • __DATE__:表示当前的编译日期;
  • __TIME__:表示当前的编译时间;
  • __STDC__:当要求程序严格遵循ANSI C标准时该标识被赋值为1;
  • __cplusplus:当编写C++程序时该标识符被定义。

  • 条件编译

    1
    2
    3
    4
    5
    #ifdef _WIN32 //windows
    ...
    #elif __linux__ //linux, _DEBUG debug模式
    ...
    #endif

#ifndef : 与#ifdef相反

#error error_message: 编译时输出自定义异常信息, 并阻止继续执行

#include 包含一个源代码文件

#undef 取消已定义的宏

  • 指针
    指针数组: int *p1[6]; 或 int *(p2[6]); p1,p2 是一个拥有 6 个 int * 元素的数组
    二维数组指针: int (*p3)[6]; p3 是一个指向拥有 6 个 int 元素数组的指针
    函数指针: int (*p4)(int, int); p4 是一个指向原型为int func(int, int)的函数指针

操作符优先级: () > [] > *

1
char * (* c[10]) (int **p);

(* c[10])表明 c 是一个指针数组, 数组的每个元素都是指针
(int **p) 代表函数参数, 接收一个二级指针的参数
char * 表示函数返回值为一个char类型的指针
合起来就是:c 是一个拥有 10 个元素的指针数组,每个指针指向一个原型为char *func(int **p);的函数

  • 文件IO

    FILE *fopen(char *filename, char *mode);

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    r	: 以只读方式打开文件,只允许读取,不允许写入。该文件必须存在。
    r+ : 以读/写方式打开文件,允许读取和写入。该文件必须存在。
    rb+ : 以读/写方式打开一个二进制文件,允许读/写数据。
    rt+ : 以读/写方式打开一个文本文件,允许读和写。
    w : 以只写方式打开文件,若文件存在则长度清为0,即该文件内容消失,若不存在则创建该文件。
    w+ : 以读/写方式打开文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则建立该文件。
    a : 以追加的方式打开只写文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留(EOF符保留)。
    a+ : 以追加方式打开可读/写的文件。若文件不存在,则会建立该文件,如果文件存在,则写入的数据会被加到文件尾后,即文件原先的内容会被保留(原来的EOF符 不保留)。
    wb : 以只写方式打开或新建一个二进制文件,只允许写数据。
    wb+ : 以读/写方式打开或建立一个二进制文件,允许读和写。
    wt+ : 以读/写方式打开或建立一个文本文件,允许读写。
    at+ : 以读/写方式打开一个文本文件,允许读或在文本末追加数据。
    ab+ : 以读/写方式打开一个二进制文件,允许读或在文件末追加数据。

rewind(); 文件指针移动到文件开头
fseek(); 文件指针移动到任意位置: int fseek ( FILE *fp, long offset, int origin );

1
2
3
文件开头	SEEK_SET	0
当前位置 SEEK_CUR 1
文件末尾 SEEK_END 2

ftell() 函数用来获取文件内部指针(位置指针)距离文件开头的字节数

  • 模块化

    头文件重复包含

    1
    2
    3
    4
    #ifndef _XYZ_H  #一般是头文件名
    #define _XYZ_H
    /* 头文件内容 */
    #endif
  • 内存分配

  1. malloc()
    原型:void* malloc (size_t size);

作用:在堆区分配 size 字节的内存空间。

返回值:成功返回分配的内存地址,失败则返回NULL。

注意:分配内存在动态存储区(堆区),手动分配,手动释放,申请时空间可能有也可能没有,需要自行判断,由于返回的是void*,建议手动强制类型转换。

  1. calloc()
    原型:void* calloc(size_t n, size_t size);

功能:在堆区分配 n*size 字节的连续空间。

返回值:成功返回分配的内存地址,失败则返回NULL。

注意:calloc() 函数是对 malloc() 函数的简单封装,参数不同,使用时务必小心,第一参数是第二参数的单元个数,第二参数是单位的字节数。

  1. realloc()
    原型:void* realloc(void *ptr, size_t size);

功能:对 ptr 指向的内存重新分配 size 大小的空间,size 可比原来的大或者小,还可以不变(如果你无聊的话)。

返回值:成功返回更改后的内存地址,失败则返回NULL。

  1. free()
    原型:void free(void* ptr);

功能:释放由 malloc()、calloc()、realloc() 申请的内存空间。

几点注意:

1
2
3
1. 每个内存分配函数必须有相应的 free 函数,释放后不能再次使用被释放的内存。
2. 在分配内存时最好不要直接用数字指定内存空间的大小,这样不利于程序的移植。因为在不同的操作系统中,同一数据类型的长度可能不一样。为了解决这个问题,C语言提供了一个判断数据类型长度的操作符,就是 sizeof。
3. free(p) 并不能改变指针 p 的值,p 依然指向以前的内存,为了防止再次使用该内存,建议将 p 的值手动置为 NULL。

本文标题:无处不在的C

文章作者:啪啪啪的指针

发布时间:2018年09月09日 - 13:09

最后更新:2018年09月12日 - 10:09

原始链接:https://www.bootvue.com/2018/09/09/cpp/

转载说明: 转载请保留原文链接及作者。