1. time函数
○ time函数---time_t time(time_t * timer),参数是一个time_t类型的指针,用于存储返回的时间值,这个参数可以为空
○ 获取当前的系统时间,返回的结果是一个time_t类型,其实就是一个大整数。
2. 动态内存分配malloc()、calloc()和free()
○ 动态内存分配
○ 通俗一点就是向计算机要内存空间,是在程序运行时,再向计算机要内存
○ 一般是用malloc函数
§ #include<stdlib.h>
§ void* malloc(size_t size);
§ 利用malloc申请到的内存空间是以字节为单位的,返回的结果是void *,一般需要类型转换为自己需要的类型
int *a;
a=(int*)malloc(n*sizeof(int)); //本语句的意思就是通过malloc函数向计算机申请一块内存空间,这个空间
的大小是n*sizeof(int),返回的是一个void*类型的指针,也就是一个指向未知类型数据的地址,之后再把这个指针
转化为我们需要的类型---int *
§ 如果申请失败了就会选择返回0或者是NULL,失败时可以通过exit()函数结束程序
® void exit(int status)
◊ 功能:关闭所有文件,终止正在执行的进程
◊ exit(1)--- 异常退出
◊ exit(x)--- x不为0就表示异常退出
◊ exit(0)--- 表示正常退出
◊ exit函数将参数传给了操作系统,以供其他程序调用
® exit和return的区别
1. return返回函数值,是关键字; exit 是一个函数。
2. return是语言级别的,它表示了调用堆栈的返回;而exit是系统调用级别的,它表示了一个进程的结束。
3. return是函数的退出(返回);exit是进程的退出。
4. return是C语言提供的,exit是操作系统提供的(或者函数库中给出的)
5. return用于结束一个函数的执行,将函数的执行信息传出给其他调用函数使用;exit函数是退出应用程序,
删除进程使用的内存空间,并将应用程序的一个状态返回给OS(操作系统),这个状态标识了应用程序的一些
运行信息,这个信息和机器和操作系统有关,一般是0为正常退出,非0为非正常退出。
6. 非主函数中调用return和exit效果很明显,但是在main函数中调用return和exit的现象就很模糊,多数情
况下现象都是一致的。
○ 利用动态内存分配技术可以创建变长数组
§ 也即声明一个指针,调用malloc(),将其返回值赋给指针,用指针访问数组元素
○ 释放内存空间free()
□ free(a);
□ 不能对同一块内存释放两次
□ 只能还申请来的空间的首地址(注意:变量可以不一样,但是地址必须一样)
□ 避免内存泄漏
calloc函数
○ long * newmem;
○ newmem = (long *)calloc(100, sizeof (long));
○ 函数声明如下:
□ void *calloc(size_t nmemb, size_t size);
○ 相比malloc函数,calloc有两个参数,前一个是申请内存单元的数量,后一个是申请内存单元的大小
○ 该函数将申请的所有内存都内置为0.
3. 程序的可用内存可以广义上分为3类
○ 供静态变量使用的静态存储区
□ 编译时确定内存数量,程序执行时被创建,结束时释放
○ 供自动存储类别变量使用的区域
□ 程序进入变量所在的块内部时,变量存在;离开时,变量消失
□ 这部分内存称为栈内存
○ 供动态内存分配使用的区域
□ malloc()、calloc()等相关函数创建
□ free()释放
□ 可以在一个函数中申请、另一个函数中释放
○ 动态内存一般要比栈内存慢
4. C程序中的类型限定符:在一条声明中多次使用同一个限定符, 多余的限定符将被忽略
a. const
□ 声明普通变量和数组时,表明数据不可以修改,是常量
□ 在指针和函数形参中使用const
§ const在*前,表示指针指向的值是const---无法用指针去修改该值、
® 若在函数形参中,用于保护数组不被修改
§ const在*后,表示指针本身的值是const---指针不能指向别处
□ 对全局数据使用
§ 使用全局数据是冒险行为
§ 数据有可能被修改,所以使用const限定,可以保证数据不变,避免这种风险
§ 文件之间共享从const数据
® 方法1:一个文件中定义式声明、其他文件中引用式声明(extern)
® 方法2:将需要共享的数据定义在头文件中、然后所有要使用该数据的文件都包含这个头文件
◊ 这种方法在头文件中定义必须使用static限定符,用于保证这个数据在每一个文件中都是私有的;
否则,待编译之后头文件展开---那么每个文件中都有一个对数据的定义式声明,这是违法的
b. volatile
□ 告知计算机该数据是一个可变数据,代理(我理解为其他的非程序本身的可以改变程序中变量数据的机制)可
以改变该数据的值
□ 该限定针对的是代理而不是程序
□ 如果有这个限定词,那么编译器在优化时,见到这个词之后就表示不优化
□ 如果没有这个限定词,那么C标准会尝试优化
□ 可以和const 同时限定某变量,两者并不冲突---const表示程序不能修改,volatile表示代理可以修改
c. restrict(限定的指针必须是访问数据对象唯一且初始的方式)
□ 也是用于编译器优化,来告诉编译器是否可以优化代码
□ 对于restrict限定的变量,如果在程序中出现可以进行合并等优化条件的语句,编译器就会认为涉及该变量的语句
之间,不存在被其他标识符修改的情况,所以可以安全的进行优化(因为该变量名是访问该变量唯一的方式,所以
其他标识符必定无法访问)
□ 如果没有restrict限定,那么为了保险起见,编译器会认为,涉及该变量的语句之间,存在其他标识符修改数据的
情况,所以不可以进行优化语句。
d. _Atomic
□ 主要应用于并发程序设计(多线程)
□ 要通过各种宏函数来访问原子类型。 当一个线程对一个原子类型的对象执行原子操作时, 其他线程不能访问该对象。
转载请注明原文地址:https://ipadbbs.8miu.com/read-11582.html