exit和return的区别
exit(0):正常运行程序并退出程序;
exit(1):非正常运行导致退出程序;
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的现象就很模糊,多数情况下现象都是一致的。
函数名: exit()
所在头文件:stdlib.h(如果是”VC6.0“的话头文件为:windows.h)
功 能: 关闭所有文件,终止正在执行的进程。
exit(1)表示异常退出.这个1是返回给操作系统的。
exit(x)(x不为0)都表示异常退出
exit(0)表示正常退出
exit()的参数会被传递给一些操作系统,包括UNIX,Linux,和MS DOS,以供其他程序使用。
数组和指针
参考博客:https://blog.youkuaiyun.com/cherrydreamsover/article/details/81741459
数组:数组是用于储存多个相同类型数据的集合。
指针:指针相当于一个变量,但是它和不同变量不一样,它存放的是其它变量在内存中的地址。
赋值、存储方式、求sizeof、初始化等不同
指针数组:char *p[4];它实际上是一个数组,数组的每个元素存放的是一个指针类型的元素。
数组指针:char (*p)[4];它实际上是一个指针,该指针指向一个数组。
数组退化为指针
数组传参时,会退化为指针,所以我们先来看看什么是退化!
(1)退化的意义:C语言只会以值拷贝的方式传递参数,参数传递时,如果只拷贝整个数组,效率会大大降低,并且在参数位于栈上,太大的数组拷贝将会导致栈溢出。
(2)因此,C语言将数组的传参进行了退化。将整个数组拷贝一份传入函数时,将数组名看做常量指针,传数组首元素的地址。
指针的大小:
cpu位数(32位数4字节,64位数8字节)
操作系统位数(32位数4字节,64位数8字节)
编译器的位数(32位数4字节,64位数8字节)
当上述3种位数不同,取最小的位数。
比如,如果CPU、系统都是64位的,但编译器是32位的,那么很显然指针只能是32位4字节大小。
变量的作用域
全局变量静态存储方式.局部变量放在栈
参考博客:变量作用域和生存期
存储说明符auto,register,extern,static,对应两种存储期:自动存储期和静态存储期。
auto和register对应自动存储期。具有自动存储期的变量在进入声明该变量的程序块时被建立,它在该程序块活动时存在,退出该程序块时撤销。
关键字extern和static用来说明具有静态存储期的变量和函数。用static声明的局部变量具有静态存储持续期(static storage duration),或静态范围(static extent)。虽然他的值在函数调用之间保持有效,但是其名字的可视性仍限制在其局部域内。静态局部对象在程序执行到该对象的声明处时被首次初始化。
float类型是如何存储的
参考博客:浮点数在内存中如何存储
四个字节,二进制存储,符号位,底数位,指数位。
在switch里面可以放浮点数吗
switch后可以不是整型,但与它匹配时会自动转换成整型。 case后必须是整型(含字符型)。
结构体中内存对齐的问题
Static的作用
参考博客:static的作用
1.修饰全局函数和全局变量:
特点:隐藏,只能在本源文件使用
2. 修饰函数的局部变量:
特点:static变量存放在静态存储区,所以它具备持久性和默认值0
只执行一次,运行一开始就开辟了内存,内存放在全局,但是局部可见
静态存储区、堆区和栈区
静态存储区
内存在程序编译的时候就已经分配好,这块内存在整个计算机内存中位于较低的地址,这块内存在程序的整个运行期间都存在。它主要存放静态数据、全局数据和常量。
栈区
在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限,栈内存存储数据是从高地址往低地址存储。
堆区
堆区亦称动态内存分配。程序在运行的时候用malloc或new申请任意大小的内存,程序员自己负责在适当的时候用free或delete释放内存。动态内存的生存期可以由我们决定,如果我们不释放内存,程序将在最后才释放掉动态内存。 但是,良好的编程习惯是:如果某动态内存不再使用,需要将其释放掉,否则,我们认为发生了内存泄漏现象。堆内存一般处于内存较低的地址(但是堆内存的内存地址高于静态内存区的内存地址),堆内存存储数据是从低地址往高地址存储数据.
注意
【规则1】用malloc 或new 申请内存之后,应该立即检查指针值是否为NULL。防止使用指针值为NULL 的内存。
【规则2】不要忘记为数组和动态内存赋初值。防止将未被初始化的内存作为右值使用。
【规则3】避免数组或指针的下标越界,特别要当心发生“多1”或者“少1”操作。
【规则4】动态内存的申请与释放必须配对,防止内存泄漏。
【规则5】用free 或delete 释放了内存之后,立即将指针设置为NULL,防止产生“野指针”。
浅谈堆和栈的理解
堆是一种特殊的完全二叉树,堆中某个节点的值总是不大于或不小于其父节点的值
详情参考博客:堆和栈的区别