C语言总结

xiaoxiao2021-02-28  67

c语言总结(一)

数据类型

数据类型是为了更好的进行内存的管理,让编译器能够确定分配好多少内存。 类型是对数据的抽象; 类型相同的数据具有想同的表示形式、存储格式以及相关操作。 数据类型分为基本类型、构造类型、指针类型。 基本数据类型的类型有以下几种

类型名名称大小(字节)介绍整型int4整型short2短整型long8长整型字符型char4字符类型浮点型float4单精度double8双精度

构造类型的介绍

名称大小(字节)介绍数组类型取决于数组存储的类型[]结构体存在内存对齐问题struct联合所有的元素相加union枚举enum

指针类型的介绍

名称大小(字节)介绍char*4(32位)或8(64位)字符型指针int*4(32位)或8(64位)整形指针int**4(32位)或8(64位)二级整型指针

在实际编程中,大量使用到typedef,给数据类型取别名,这种方法方便在程序开发时修改数据类型,也方便程序员维护和阅读 typedef unsigned int uint; void数据类型 void不能直接定义变量,否则编译器会报错,当有viod*表明改指针可以指向任何类型的数据,void一般使用到对函数返回的限定和函数参数的限定 例如:void test(void);//其中函数参数也可以省略表示void sizeof操作符 sizeof为C语言中的一个函数,用于计算变量或数据类型的大小,返回的该变量或数据类型的开辟的大小值,返回的类型为unsigned int; 使用方法:sizeof(变量)、sizeof(数据类型); 当计算指针的时候,要区别好是计算指针指向的空间的大小,还是计算指针本身的大小,指针本身的大小根据操作系统确定,一般为4字节或8字节。

变量

在c程序中,能够既能读又能写的被称之为变量。那些一旦初始化的就不能改变的,为只读的,被称作为常量,常量存储在内存的常量区。 变量名的本质为一段连续内存空间的别名 程序通过变量来申请和命名内存空间:int a = 0; 通过变量名访问内存空间; 不是向变量名写数据,而是向变量所代表的内存空间中读写数据 修改变量的两种方式:

(1)直接通过变量名修改 a = 20;(2)使用指针间接修改 int *p = &a; *p = 30;

程序的内存分区模型

当我们想执行我们编写的程序,首先要对程序进行编译,编译的过程分为4个步骤,预处理、编译、汇编、链接。

预处理:将所有的#define删除,并展开所有的宏定义、处理所有的条件预编译指令,如#ifdef #elif #else #endif等、出来#inlucde预编译指令,将包含的文件插入到预编译指令的位置、删除所有的注释“//”“/* */”、添加行号和文件标识,以便编译时调试用的行号及编译错误警告行号、保留所有的#pragma编译,因为编译器需要使用它们。 使用指令为:gcc -E hello.c -o hello.i编译:就是把预处理完的文件进行一系列的词法分析,语法分析,语法分析及优化后生成相应的汇编代码 使用的指令为:gcc -S hello.i -o hello.s汇编:将汇编代码转变成机器可以执行的命令,每一个汇编都对应一条机器指令。汇编对于编译过程比较简单,根据汇编指令和机器指令对照表一一翻译即可。 使用的指令为:gcc -c hello.s -o hello.o链接:通过条用链接器ID来链接程序运行需要的idaho堆目标文件,以及所依赖的其他库文件,最后生成可执行的文件 使用的指令为:gcc hello.o -o hello 链接处理分为两种动态链接和静态链接 (1)静态链接:函数代码将从其所在地静态链接库中被拷贝到最终的可执行程序中,而运行的时候不需要其他的库文件。 (2)动态链接:函数的代码被放到称作是动态链接库或共享的某个文件中,链接程序此时所作的只是在最终的可执行程序中记录下共享对象的名字以及其它少量的登记信息,在程序被执行的时候,再将动态库的全部内容映射到运行时相应的进程的虚地址空间。 使用动态链接可以使得可执行文件的大小变得很小,而且当共享对象被多个进程使用时能节约一些内存,但是在某些情况下动态链接可能带来一些性能上的损害。 静态库和共享库:在windows中静态库是以 .lib 为后缀的文件,共享库是以 .dll 为后缀的文件。在Linux中静态库是以 .a 为后缀的文件,共享库是以 .so为后缀的文件。

对于可执行文件,程序内部已经分好三部分信息,分别为代码区(text)、数据区(data)和未初始化数据区(bss)

代码区:存放CPU执行的指令。通常代码区是可共享的,这样使得频繁被执行的程序,在内存中只需要存储一份,节省内存空间,代码区通常是只读的,防止程序意外被修改全局初始化数据区/静态数据区(data):该区包含了在程序中明确被初始化的全局变量、已经初始化的静态变量和常量未初始化数据区(bss):存入的是全局未初始化变量和未初始化静态变量。未初始化数据的数去在程序开始执行之前被内核初始化为0或空(NULL)

程序在加载到内存前,代码区和全局区(data和bss)的大小是固定的,程序运行期间不能改变。然后,运行可执行程序,操作系统把物理硬盘程序加载到内存,除了根据可执行的信息分出代码区、数据区和未初始化数据区之外,还额为增加了栈区、堆区。

代码区:加载的是可执行文件代码,所有的可执行的代码都加载到代码区,这块内存是不可以在运行期间修改的。未初始化数据区(bss):加载的是可执行文件的bss段,生命周期为整个程序运行过程全局初始化数据区/静态数据区(data):加载的是可执行程序的数据段(data),生命周期为整个程序的运行过程。栈区(stack):栈是一种先进后出的内存结构,由编译器自动分配内存,存放函数的参数值、返回值、局部变量等。在程序运行过程中实时加载和释放,因此,局部变量的生命周期为申请到释放该段栈空间。栈区默认大小为1M,可修改。堆区(heap):堆是一个大容器,它的容量远远大于栈,但没有栈那样的先进先出的顺序。用于动态内存分配。堆在内存中位于BSS和栈区之间。一般由程序员分配和释放,若程序员不释放,程序结束时由操作系统回收,在这注意内存泄漏的问题。 类型作用域生命周期存储位置auto变量一对{}内当前函数栈区static局部变量一对{}内整个程序运行期初始化在Data段,未初始化在bss段extern变量整个程序整个程序运行期初始化在Data段,未初始化在bss段static全局变量当前文件整个程序运行期初始化在Data段,未初始化在bss段extern函数整个程序整个程序运行期代码区static函数当前文件整个程序运行期代码区register变量一对{}内当前函数运行时存储在CPU寄存器字符串常量当前文件整个程序运行期data段

对于堆有以下函数

(1)void *calloc(size_t nmemb, size_t size); 在堆空间分配nmemb块长度为size字节的连续区域。calloc自动将分配的内存置0 返回值:如果成功,返回空间的起始地址,失败,返回NULL(2)void *malloc(size_t size) 在堆空间分配字节长度为size大小的连续区域,malloc不会初始化开辟的内存。(3)void *realloc(void *ptr, size_t size); 重新分配用malloc或calloc函数在堆中分配的内存空间大小,realloc不会自动清理增加的内存,需要手动清理,如果指定的地址后面有连续的空间,那么就会在已有地址基础上增加内存,如果指定的工具后面没有空间,那么realloc会重新分配新的连续内存,把旧内存的值拷贝到新内存,同时释放旧内存。在使用realloc扩展内存时,为了防止开辟空间失败,应使用一个中间指针变量。开辟成功后再将开辟的地址赋值给原来的指针变量。 返回值:如果成功,返回空间的起始地址,失败,返回NULL
转载请注明原文地址: https://www.6miu.com/read-59897.html

最新回复(0)