04 2018 档案

摘要:函数的定义 函数由函数名以及一组操作数类型唯一地表示。函数的操作数,也即形参,在一对圆括号中声明,形参与形参之间以逗号分隔。函数执行的运算在一个称为函数体的块语句中定义。每一个函数都有一个相关联的返回类型。 函数的调用 C++ 语言使用调用操作符(即一对圆括号)实现函数的调用。正如其他操作符一样,调 阅读全文 »
posted @ 2018-04-30 20:04 刘-皇叔 阅读(346) 评论(0) 推荐(0) 编辑
摘要:异常就是运行时出现的不正常,例如运行时耗尽了内存或遇到意外的非法输入。异常存在于程序的正常功能之外,并要求程序立即处理。 在设计良好的系统中,异常是程序错误处理的一部分。当程序代码检查到无法处理的问题时,异常处理就特别有用。在这些情况下,检测出问题的那部分程序需要一种方法把控制权转到可以处理这个问题 阅读全文 »
posted @ 2018-04-30 14:49 刘-皇叔 阅读(1358) 评论(0) 推荐(1) 编辑
摘要:break 语句 break 语句用于结束最近的 while、do while、for 或 switch 语句,并将程序的执行权传递给紧接在被终止语句之后的语句。 break 终止了 while 循环。执行权交给紧跟在 while 语句后面的if 语句,程序继续执行。 break 只能出现在循环或 阅读全文 »
posted @ 2018-04-30 14:16 刘-皇叔 阅读(496) 评论(0) 推荐(0) 编辑
摘要:while 语句 当条件为真时,while 语句反复执行目标语句。它的语法形式如下: 只要条件 condition 的值为 true,执行语句 statement(通常是一个块语句)。condition 不能为空。如果第一次求解 condition 就产生 false 值,则不执行 statemen 阅读全文 »
posted @ 2018-04-30 10:20 刘-皇叔 阅读(638) 评论(0) 推荐(0) 编辑
摘要:if语句 if 语句根据特定表达式是否为真来有条件地执行另一个语句。if 语句有两种形式:其中一种带 else 分支而另一种则没有。根据语法结构,最简单的 if 语句是这样的: 其中的 condition 部分必须用圆括号括起来。 通常,statement 部分可以是复合语句,即用花括号括起来的块语 阅读全文 »
posted @ 2018-04-30 09:22 刘-皇叔 阅读(436) 评论(0) 推荐(0) 编辑
摘要:if 语句根据特定表达式是否为真来有条件地执行另一个语句。if 语句有两种形式:其中一种带 else 分支而另一种则没有。根据语法结构,最简单的 if 语句是这样的: 其中的 condition 部分必须用圆括号括起来。 通常,statement 部分可以是复合语句,即用花括号括起来的块语句。 如果 阅读全文 »
posted @ 2018-04-30 09:22 刘-皇叔 阅读(582) 评论(0) 推荐(0) 编辑
摘要:声明语句 在 C++ 中,对象或类的定义或声明也是语句。尽管定义语句这种说法也许更准确些,但定义语句经常被称为声明语句。 复合语句(块) 复合语句,通常被称为块,是用一对花括号括起来的语句序列(也可能是空的)。块标识了一个作用域,在块中引入的名字只能在该块内部或嵌套在块中的子块里访问。通常,一个名字 阅读全文 »
posted @ 2018-04-29 23:37 刘-皇叔 阅读(1017) 评论(0) 推荐(0) 编辑
摘要:C++ 语言既有只完成单一任务的简单语句,也有作为一个单元执行的由一组语句组成的复合语句。和大多数语言一样,C++也提供了实现条件分支结构的语句以及重复地执行同一段代码的循环结构。 简单语句 C++ 中,大多数语句以分号结束。表达式语句用于计算表达式。但执行下面的语句 却没有任何意义:因为计算出来的 阅读全文 »
posted @ 2018-04-29 23:04 刘-皇叔 阅读(263) 评论(0) 推荐(0) 编辑
摘要:Associativity and Operator 操作符及其结合性 Function 功能 Use 用法 L :: global scope(全局作用域) :: name L :: class scope(类作用域) class :: name L :: namespace scope(名字空间 阅读全文 »
posted @ 2018-04-29 22:46 刘-皇叔 阅读(344) 评论(0) 推荐(0) 编辑
摘要:隐式转换 何时发生隐式类型转换 在表达式中,比int类型小的整型会首先被提升为较大的整数类型。 在条件中,非布尔值转换成布尔值。 初始化过程中,初始值转换成变量的类型。 在赋值语句中,右侧对象转换成左侧对象的类型。 如果算术运算符或关系运算符的对象有多种类型,需要转换成同一种类型。 在函数调用时也将 阅读全文 »
posted @ 2018-04-29 21:48 刘-皇叔 阅读(309) 评论(0) 推荐(0) 编辑
摘要:逗号表达式是一组由逗号分隔的表达式,这些表达式从左向右计算。逗号表达式的结果是其最右边表达式的值。如果最右边的操作数是左值,则逗号表达式的值也是左值。此类表达式通常用于 for 循环: 上述的 for 语句在循环表达式中使 ix 自增 1 而 cnt 自减 1。每次循环均要修改 ix 和 cnt 的 阅读全文 »
posted @ 2018-04-29 18:12 刘-皇叔 阅读(155) 评论(0) 推荐(0) 编辑
摘要:基本概念 位操作符使用整型的操作数。位操作符将其整型操作数视为二进制位的集合,为每一位提供检验和设置的功能。另外,这类操作符还可用于bitset 类型的操作数,该类型具有这里所描述的整型操作数的行为。 操作符 功能 用法 ~ bitwise NOT(位求反) ~expr << left shift( 阅读全文 »
posted @ 2018-04-29 18:09 刘-皇叔 阅读(500) 评论(0) 推荐(0) 编辑
摘要:sizeof 操作符的作用是返回一个对象或类型名的长度,返回值的类型为size_t,长度的单位是字节。size_t 表达式的结果是编译时常量,该操作符有以下三种语法形式: sizeof (type name); sizeof (expr); sizeof expr; 将 sizeof 应用在表达式 阅读全文 »
posted @ 2018-04-29 17:55 刘-皇叔 阅读(215) 评论(0) 推荐(0) 编辑
摘要:成员访问运算符 点运算符和箭头运算符都可以用于访问成员,其中,点运算符获取类对象的一个成员,箭头运算符与点运算符有关。 因为解引用运算符的优先级低于点运算符,所以解引用运算的子表达式两端必须加上括号,若是没有括号,代码的意义就大不相同: 条件操作符 条件操作符是 C++ 中唯一的三元操作符,它允许将 阅读全文 »
posted @ 2018-04-29 17:44 刘-皇叔 阅读(821) 评论(0) 推荐(0) 编辑
摘要:自增(++)和自减(--)操作符为对象加 1 或减 1 操作提供了方便简短的实现方式。它们有前置和后置两种使用形式。 前自增操作,该操作使其操作数加 1,操作结果是修改后的值,前自减操作使其操作数减 1。这两种操作符的后置形式同样对其操作数加 1(或减 1),但操作后产生操作数原来的、未修改的值作为 阅读全文 »
posted @ 2018-04-29 13:09 刘-皇叔 阅读(415) 评论(0) 推荐(0) 编辑
摘要:赋值操作符的左操作数必须是非 const 的左值。下面的赋值语句是不合法的: 如果赋值运算符的左右两个运算对象类型不同,则右侧运算对象将转换成左侧运算对象的类型: 赋值运算满足右结合律 赋值运算符满足右结合律: 对于多重赋值语句中的每一个对象,它的类型或者与右边对象的类型相同,或者可由右边对象的类型 阅读全文 »
posted @ 2018-04-29 12:45 刘-皇叔 阅读(471) 评论(0) 推荐(1) 编辑
摘要:关系操作符和逻辑操作符使用算术或指针类型的操作数,并返回bool 类型的值。 操作符 功能 用法 ! logical NOT(逻辑非) !expr < less than(小于) expr < expr <= less than or equal(小于等于) expr <= expr > great 阅读全文 »
posted @ 2018-04-29 10:48 刘-皇叔 阅读(642) 评论(0) 推荐(0) 编辑
摘要:操作符 功能 用法 + unary plus(一元正号) + expr - unary minus(一元负号) - expr * multiplication(乘法) expr * expr / division(除法) expr / expr % remainder(求余) expr % expr 阅读全文 »
posted @ 2018-04-29 09:59 刘-皇叔 阅读(343) 评论(0) 推荐(0) 编辑
摘要:表达式由一个或多个操作数通过操作符组合而成。最简单的表达式仅包含一个字面值常量或变量。较复杂的表达式则由操作符以及一个或多个操作数构成。 基本概念 一元操作符、二元操作符、三元操作符 C++提供了一元操作符和二元操作符两种操作符。作用在一个操作数上的操作符称为一元操作符,如取地址操作符(&)和解引用 阅读全文 »
posted @ 2018-04-29 09:28 刘-皇叔 阅读(158) 评论(0) 推荐(0) 编辑
摘要:严格地说,C++ 中没有多维数组,通常所指的多维数组其实就是数组的数组: 如果数组的元素又是数组,则称为二维数组,其每一维对应一个下标: 第一维通常称为行(row),第二维则称为列(column)。C++ 中并未限制可用的下标个数,也就是说,我们可以定义元素是数组(其元素又是数组,如此类推)的数组。 阅读全文 »
posted @ 2018-04-28 18:12 刘-皇叔 阅读(330) 评论(0) 推荐(0) 编辑
摘要:尽管 C++ 支持 C 风格字符串,但不应该在 C++ 程序中使用这个类型。C 风格字符串常常带来许多错误,是导致大量安全问题的根源。 字符串字面值的类型就是const char 类型的数组。 C++ 从 C 语言继承下来的一种通用结构是 C 风格字符串,而字符串字面值就是该类型的实例。实际上,C 阅读全文 »
posted @ 2018-04-28 18:06 刘-皇叔 阅读(1490) 评论(0) 推荐(0) 编辑
摘要:数组是由类型名、标识符和维数组成的复合数据类型,类型名规定了存放在数组中的元素的类型,而维数则指定数组中包含的元素个数。 数组定义中的类型名可以是内置数据类型或类类型;除引用之外,数组元素的类型还可以是任意的复合类型。没有所有元素都是引用的数组。 数组的定义和初始化 数组的维数必须用值大于等于 1 阅读全文 »
posted @ 2018-04-28 17:59 刘-皇叔 阅读(236) 评论(0) 推荐(0) 编辑
摘要:vector 是同一种类型的对象的集合,每个对象都有一个对应的整数索引值。把 vector称为容器,是因为它可以包含其他对象。 使用 vector 之前,必须包含相应的头文件: vector 是一个类模板(class template)。因此,可以定义保存 string 对象的 vector,或保存 阅读全文 »
posted @ 2018-04-28 10:04 刘-皇叔 阅读(1768) 评论(0) 推荐(0) 编辑
摘要:除了使用下标来访问 vector 对象的元素外,标准库还提供了另一种访问元素的方法:使用迭代器(iterator) 。迭代器是一种检查容器内元素并遍历元素的数据类型。 所有的标准库容器都定义了相应的迭代器类型,而只有少数的容器支持下标操作。因为迭代器对所有的容器都适用,现代 C++ 程序更倾向于使用 阅读全文 »
posted @ 2018-04-27 21:37 刘-皇叔 阅读(444) 评论(0) 推荐(0) 编辑
摘要:string 类型支持长度可变的字符串,标准库 string 类型的满足对对字符串的一般应用。 与其他的标准库类型一样,用户程序要使用 string 类型对象,必须包含相关头文件。如果提供了合适的 using 声明,那么编写出来的程序将会变得简短些: string 对象的定义和初始化 初始化stri 阅读全文 »
posted @ 2018-04-27 17:30 刘-皇叔 阅读(238) 评论(0) 推荐(0) 编辑
摘要:使用 using 声明可以在不需要加前缀 namespace_name:: 的情况下访问命名空间中的名字。using 声明的形式如下: 一旦使用了 using 声明,我们就可以直接引用名字,而不需要再引用该名字的命名空间。 没有 using 声明,而直接使用命名空间中名字的未限定版本是错误的,尽管有 阅读全文 »
posted @ 2018-04-27 16:01 刘-皇叔 阅读(1219) 评论(0) 推荐(0) 编辑
摘要:类型别名 类型别名是一个名字,它是某种类型的同义词,定义类型别名有两种方法: 新标准规定了新的方法,使用别名声明来定义类型的别名: 这种方法用关键字using作为别名声明的开始,其后紧跟别名和等号,其作用是把等号左侧的名字规定成等号右侧类型的别名。 指针、常量和类型别名 如果某个类型别名指代的是复合 阅读全文 »
posted @ 2018-04-23 21:41 刘-皇叔 阅读(279) 评论(0) 推荐(0) 编辑
摘要:定义 const 对象 const 限定符提供了一个解决办法,它把一个对象转换成一个常量。 因为常量在定义后就不能被修改,所以定义时必须初始化 : const 对象默认为文件的局部变量 在全局作用域里定义非 const 变量时,它在整个程序中都可以访问。我们可以把一个非 const 变更定义在一个文 阅读全文 »
posted @ 2018-04-22 11:51 刘-皇叔 阅读(278) 评论(0) 推荐(0) 编辑
摘要:引用 引用是一种复合类型,通过在变量名前添加“&”符号来定义。复合类型是指用其他类型定义的类型。在引用的情况下,每一种引用类型都“关联到”某一其他类型。不能定义引用类型的引用,但可以定义任何其他类型的引用。 引用必须用与该引用同类型的对象初始化: 引用是别名 因为引用只是它绑定的对象的另一名字,作用 阅读全文 »
posted @ 2018-04-22 11:40 刘-皇叔 阅读(469) 评论(0) 推荐(0) 编辑
摘要:变量 变量提供了程序可以操作的有名字的存储区。C++ 中的每一个变量都有特定的类型,该类型决定了变量的内存大小和布局、能够存储于该内存中的值的取值范围以及可应用在该变量上的操作集。C++ 程序员常常把变量称为“变量”或“对象(object)”。 左值和右值 左值(发音为 ell-value):左值可 阅读全文 »
posted @ 2018-04-22 09:31 刘-皇叔 阅读(257) 评论(0) 推荐(0) 编辑
摘要:类似42 这样的值,在程序中被当作字面值常量。称之为字面值是因为只能用它的值称呼它, 称之为常量是因为它的值不能修改。每个字面值都有相应的类型,例如:0 是 int 型,3.14159 是 double 型。只有内置类型存在字面值,没有类类型的字面值。因此,也没有任何标准库类型的字面值。 整型字面值 阅读全文 »
posted @ 2018-04-21 22:48 刘-皇叔 阅读(2007) 评论(0) 推荐(0) 编辑
摘要:C++ 定义了一组表示整数、浮点数、单个字符和布尔值的算术类型,另外还定义了一种称为 void 的特殊类型。 算术类型的存储空间依机器而定。这里的存储空间是指用来表示该类型的位(bit)数。C++标准规定了每个算术类型的最小存储空间,但它并不阻止编译器使用更大的存储空间。 C++ 算术类型 : 类型 阅读全文 »
posted @ 2018-04-21 14:17 刘-皇叔 阅读(203) 评论(0) 推荐(0) 编辑
摘要:我们通常希望自己编写的程序能够在异常的情况下也能作出相应的处理,而不至于程序莫名其妙地中断或者中止运行了。在设计程序时应充分考虑各种异常情况,并加以处理。 在C++中,一个函数能够检测出异常并且将异常返回,这种机制称为抛出异常。当抛出异常后,函数调用者捕获到该异常,并对该异常进行处理,我们称之为异常 阅读全文 »
posted @ 2018-04-21 13:40 刘-皇叔 阅读(44867) 评论(0) 推荐(6) 编辑
摘要:C++内联函数(inline) C++语言新增关键字 inline,用于将一个函数声明为内联函数。在程序编译时,编译器会将内联函数调用处用函数体替换,这一点类似于C语言中的宏扩展。 采用内联函数可以有效避免函数调用的开销,程序执行效率更高。使用内联函数的缺点就是,如果被声明为内联函数的函数体非常大, 阅读全文 »
posted @ 2018-04-21 13:25 刘-皇叔 阅读(571) 评论(0) 推荐(0) 编辑
摘要:在C++语言中新增了四个关键字static_cast、const_cast、reinterpret_cast和dynamic_cast。这四个关键字都是用于强制类型转换的。 static_cast 在C++语言中static_cast用于数据类型的强制转换,强制将一种数据类型转换为另一种数据类型。例 阅读全文 »
posted @ 2018-04-21 13:14 刘-皇叔 阅读(1348) 评论(0) 推荐(0) 编辑
摘要:C++的输入输出(cout和cin) 在C语言中,通常会在采用格式化输入输出函数printf和scanf用于输入或输出数据或信息。在C++语言中,C语言的这一套输入输出库我们仍能使用,但是C++语言又自定义了一套新的、更容易使用的输入输出库。 在C++程序中,输入与输出可以看做是一连串的数据流,输入 阅读全文 »
posted @ 2018-04-21 12:45 刘-皇叔 阅读(823) 评论(0) 推荐(0) 编辑
摘要:C++语言引入命名空间(Namespace)这一概念主要是为了避免命名冲突,其关键字为 namespace。 不同的人开发同一个系统,不可避免地会出现变量或函数的命名冲突,当所有人的代码测试通过,没有问题时,将所有人的代码结合到一起,因为变量或函数重名而导致的问题将会造成一定的混乱,例如: 如上所示 阅读全文 »
posted @ 2018-04-21 12:43 刘-皇叔 阅读(212) 评论(0) 推荐(0) 编辑
摘要:C++概述 20世纪80年代,AT&T Bell(贝尔)实验室的Bjarne Stroustrup博士及其同事在C语言的基础上成功开发出C++语言。C++语言是一种混合型语言,它保留了C语言所有的优点,同时又增添了面向对象的编程机制,我们可以将C++语言视为C语言的改进和扩展。 基于C语言开发的C+ 阅读全文 »
posted @ 2018-04-21 12:37 刘-皇叔 阅读(1156) 评论(0) 推荐(0) 编辑
摘要:ELF文件格式是一个开放标准,各种UNIX系统的可执行文件都采用ELF格式,它有三种不同的类型: 可重定位的目标文件(Relocatable,或者Object File) 可执行文件(Executable) 共享库(Shared Object,或者Shared Library) ELF格式提供了两种 阅读全文 »
posted @ 2018-04-08 16:04 刘-皇叔 阅读(386) 评论(0) 推荐(0) 编辑
摘要:虚拟内存管理示例 我们知道操作系统利用体系结构提供的VA到PA的转换机制实现虚拟内存管理。有了共享库的基础知识之后,现在我们可以进一步理解虚拟内存管理了。首先分析一个例子: 用ps命令查看当前终端下的进程,得知bash进程的id是29977,然后用cat /proc/29977/maps命令查看它的 阅读全文 »
posted @ 2018-04-08 15:53 刘-皇叔 阅读(1221) 评论(0) 推荐(0) 编辑
摘要:动态函数库同共享函数库是一个东西(在linux上叫共享对象库, 文件后缀是.so ,windows上叫动态加载函数库,文件后缀是.dll)。 Linux中命名系统中共享库的规则: 共享函数库中的函数是在当一个可执行程序在启动的时候被加载。如果一个共享函数库正常安装,所有的程序在重新运行的时候都可以自 阅读全文 »
posted @ 2018-04-08 15:16 刘-皇叔 阅读(719) 评论(0) 推荐(0) 编辑
摘要:创建静态库 有时候需要把一组代码编译成一个库,这个库在很多项目中都要用到,例如libc就是这样一个库,我们在不同的程序中都会用到libc中的库函数(例如printf),也会用到libc中的变量。 我们把stack.c拆成四个程序文件: 这些文件的目录结构是: 我们把stack.c、 push.c、 阅读全文 »
posted @ 2018-04-08 09:05 刘-皇叔 阅读(216) 评论(0) 推荐(0) 编辑
摘要:我前面关于stack.c和main.c的讨论。 stack.c这个模块封装了top和stack两个变量,导出了push、 pop、 is_empty三个函数接口,已经设计得比较完善了。但是使用这个模块的每个程序文件都要写三个函数声明也是很麻烦的,假设又有一个foo.c也使用这个模块, main.c和 阅读全文 »
posted @ 2018-04-08 08:53 刘-皇叔 阅读(181) 评论(0) 推荐(0) 编辑
摘要:在上一节我们把两个程序文件放在一起编译链接,main.c用到的函数push、 pop和is_empty由stack.c提供,其实有一点小问题,我们用-Wall选项编译main.c可以看到: 由于编译器在处理函数调用代码时没有找到函数原型,只好根据函数调用代码做隐式声明,把这三个函数声明为: 为什么编 阅读全文 »
posted @ 2018-04-08 08:46 刘-皇叔 阅读(572) 评论(0) 推荐(2) 编辑
摘要:考虑下面几个程序段: 编译时可以一步编译 : 也可以多步编译: 用nm命令查看目标文件的符号表,会发现main.o中有未定义的符号push、 pop、 is_empty、 putchar,前三个符号在stack.o中实现了,链接生成可执行文件main时可以做符号解析,而putchar是libc的库函 阅读全文 »
posted @ 2018-04-08 08:28 刘-皇叔 阅读(235) 评论(0) 推荐(0) 编辑
摘要:一层指针的参数 如果函数接口有指针参数,既可以把指针所指向的数据传给函数使用(称为传入参数),也可以由函数填充指针所指的内存空间,传回给调用者使用(称为传出参数)。有些函数的指针参数同时担当了这两种角色,既是传入参数又是传出参数,这称为Value-result参数。 传入参数 void func(c 阅读全文 »
posted @ 2018-04-08 00:09 刘-皇叔 阅读(709) 评论(0) 推荐(0) 编辑
摘要:不完全类型是暂时没有完全定义好的类型,编译器不知道这种类型该占几个字节的存储空间,例如: 具有不完全类型的变量可以通过多次声明组合成一个完全类型,比如数组str声明两次: 当编译器碰到第一个声明时,认为str是一个不完全类型,碰到第二个声明时str就组合成完全类型了,如果编译器处理到程序文件的末尾仍 阅读全文 »
posted @ 2018-04-07 23:49 刘-皇叔 阅读(374) 评论(0) 推荐(0) 编辑
摘要:指向数组的指针 以下定义一个指向数组的指针,该数组有10个int元素: []比*有更高的优先级,如果a先和*结合则表示a是一个指针,如果a先和[]结合则表示a是一个数组。 int *a[10];这个定义可以拆成两句: t代表int *类型, a则是由这种类型的元素组成的数组。 int (*a)[10 阅读全文 »
posted @ 2018-04-07 23:41 刘-皇叔 阅读(465) 评论(0) 推荐(0) 编辑
摘要:要通过指针p访问结构体成员可以写成(*p).c和(*p).num,为了书写方便, C语言提供了->运算符,也可以写成p->c和p->num。 阅读全文 »
posted @ 2018-04-07 23:28 刘-皇叔 阅读(174) 评论(0) 推荐(0) 编辑
摘要:const限定符和指针结合起来常见的情况有以下几种。: 这两种写法是一样的, a是一个指向const int型的指针, a所指向的内存单元不可改写,所以(*a)++是不允许的,但a可以改写,所以a++是允许的。 a是一个指向int型的const指针, *a是可以改写的,但a不允许改写。 a是一个指向 阅读全文 »
posted @ 2018-04-07 23:27 刘-皇叔 阅读(283) 评论(0) 推荐(0) 编辑
摘要:(1)首先指针pa指向a[0]的地址,注意后缀运算符的优先级高于单目运算符,所以是取a[0]的地址,而不是取a的地址。然后pa++让pa指向下一个元素(也就是a[1]),由于pa是int *指针,一个int型元素占4个字节,所以pa++使pa所指向的地址加4,注意不是加1。 (2)a[2]和pa[2 阅读全文 »
posted @ 2018-04-07 23:19 刘-皇叔 阅读(725) 评论(0) 推荐(0) 编辑
摘要:我们知道,调用函数的传参过程相当于用实参定义并初始化形参, swap(&i, &j)这个调用相当于: 所以px和py分别指向main函数的局部变量i和j,在swap函数中读写*px和*py其实是读写main函数的i和j。尽管在swap函数的作用域中访问不到i和j这两个变量名,却可以通过地址访问它们, 阅读全文 »
posted @ 2018-04-07 23:11 刘-皇叔 阅读(1398) 评论(0) 推荐(0) 编辑
摘要:野指针和空指针 在堆栈上分配的变量初始值是不确定的,也就是说指针p所指向的内存地址是不确定的,后面用*p访问不确定的地址就会导致不确定的后果,如果导致段错误还比较容易改正,如果意外改写了数据而导致随后的运行中出错,就很难找到错误原因了。像这种指向不确定地址的指针称为“野指针”(Unbound Poi 阅读全文 »
posted @ 2018-04-07 23:05 刘-皇叔 阅读(395) 评论(0) 推荐(0) 编辑
摘要:1、三连符替换成相应的单字符(例如用??=表示#字符。)。 2、把用\字符续行的多行代码接成一行。例如: 经过这个预处理步骤之后接成一行: 这种续行的写法要求\后面紧跟换行,中间不能有其它空白字符。 3、把注释(不管是单行注释还是多行注释)都替换成一个空格。 4、经过以上两步之后去掉了一些换行,有的 阅读全文 »
posted @ 2018-04-07 22:52 刘-皇叔 阅读(918) 评论(0) 推荐(0) 编辑
摘要:关键字就是已被C语言本身使用,不能作为其它标识符由ANSI标准定义的C语言关键字共32个: 根据关键字的作用,可以将关键字分为数据类型关键字和流程控制关键字两大类。 (1) 数据类型关键字 1) 基本数据类型(5个) void;char;int;float;double 2) 类型修饰关键字(4个) 阅读全文 »
posted @ 2018-04-07 22:37 刘-皇叔 阅读(237) 评论(0) 推荐(0) 编辑
摘要:扩展的行内汇编 在扩展的行内汇编中,可以将 C 语言表达式指定为汇编指令的操作数,而且不用去管如何将 C 语言表达式的值读入寄存器,以及如何将计算结果写回 C 变量,你只要告诉程序中 C 语言表达式与汇编指令操作数之间的对应关系即可,GCC 会自动插入代码完成必要的操作。 使用内嵌汇编,要先编写汇编 阅读全文 »
posted @ 2018-04-07 22:33 刘-皇叔 阅读(1635) 评论(0) 推荐(0) 编辑
摘要:Linux 操作系统内核代码绝大部分使用 C 语言编写,只有一小部分使用汇编语言编写,例如与特定体系结构相关的代码和对性能影响很大的代码。 GCC 提供了内嵌汇编的功能,可以在 C 代码中直接内嵌汇编语言语句,大大方便了程序设计。 基本行内汇编 基本行内汇编很容易理解,一般是按照下面的格式: 同时“ 阅读全文 »
posted @ 2018-04-07 22:31 刘-皇叔 阅读(214) 评论(0) 推荐(0) 编辑
摘要:结构体 main函数中几条语句的反汇编结果如下: 从访问结构体成员的指令可以看出,结构体的四个成员在栈上是这样排列的: 虽然栈是从高地址向低地址增长的,但结构体成员也是从低地址向高地址排列的,这一点和数组类似。但有一点和数组不同,结构体的各成员并不是一个紧挨一个排列的,中间有空隙,称为填充(Padd 阅读全文 »
posted @ 2018-04-07 22:29 刘-皇叔 阅读(424) 评论(0) 推荐(0) 编辑
摘要:我们在全局作用域和main函数的局部作用域各定义了一些变量,并且引入一些新的关键字const、 static、 register来修饰变量,那么这些变量的存储空间是怎么分配的呢?我们编译之后用readelf命令看它的符号表,了解各变量的地址分布。注意在下面的清单中我把符号表按地址从低到高的顺序重新排 阅读全文 »
posted @ 2018-04-07 22:19 刘-皇叔 阅读(247) 评论(0) 推荐(0) 编辑
摘要:存储类修饰符 存储类修饰符(Storage Class Specifier)有以下几种关键字,可以修饰变量或函数声明: (1)static,用它修饰的变量的存储空间是静态分配的,用它修饰的文件作用域的变量或函数具有Internal Linkage。 (2)auto,用它修饰的变量在函数调用时自动在栈 阅读全文 »
posted @ 2018-04-07 22:14 刘-皇叔 阅读(280) 评论(0) 推荐(0) 编辑
摘要:作用域 作用域是程序中定义的变量所存在的区域,超过该区域变量就不能被访问。编译器可以确认4种不同类型的作用域:文件作用域,函数作用域,代码块作用域,原型作用域。 代码块作用域 位于一对花括号之间的语句称为语句块,任何在代码块的开始位置声明的标识符都具有代码块作用域,表示它们可以被这个代码块中的所有语 阅读全文 »
posted @ 2018-04-07 22:07 刘-皇叔 阅读(712) 评论(0) 推荐(0) 编辑
摘要:汇编程序的入口是_start,而C程序的入口是main函数。 汇编和链接步骤是: 以前我们常用gcc main.c -o main命令编译一个程序,其实也可以分三步做,第一步生成汇编代码,第二步生成目标文件,第三步生成可执行文件: -S选项生成汇编代码, -c选项生成目标文件,此外-E选项只做预处理 阅读全文 »
posted @ 2018-04-07 16:03 刘-皇叔 阅读(1359) 评论(0) 推荐(0) 编辑
摘要:下面一段C程序: 如果在编译时加上-g选项,那么用objdump反汇编时可以把C代码和汇编代码穿插起来显示,这样C代码和汇编代码的对应关系看得更清楚。反汇编的结果很长,以下只列出我们关心的部分。 要查看编译后的汇编代码,其实还有一种办法是gcc -S main.c,这样只生成汇编代码main.s,而 阅读全文 »
posted @ 2018-04-07 16:01 刘-皇叔 阅读(2978) 评论(0) 推荐(0) 编辑
摘要:汇编程序1 将这段程序保存为hello.s,然后用汇编器as把汇编程序中的助记符翻译成机器指令(汇编指令与机器指令是对应的)生成目标文件hello.o。然后用链接器ld把目标文件hello.o链接成可执行文件hello(虽然只有一个目标文件但是也需要经过链接才能成为可执行文件因为链接器要修改目标文件 阅读全文 »
posted @ 2018-04-07 15:52 刘-皇叔 阅读(3558) 评论(0) 推荐(0) 编辑
摘要:访问内存时在指令中可以用多种方式表示内存地址。内存寻址在指令中可以表示成如下的通用格式: ADDRESS_OR_OFFSET(%BASE_OR_OFFSET,%INDEX,MULTIPLIER) 它所表示的地址可以这样计算出来: FINAL ADDRESS = ADDRESS_OR_OFFSET + 阅读全文 »
posted @ 2018-04-07 15:50 刘-皇叔 阅读(887) 评论(0) 推荐(0) 编辑
摘要:通用寄存器 x86的通用寄存器有eax、ebx、ecx、edx、edi、esi。这些寄存器在大多数指令中是可以任意使用的。但有些指令限制只能用其中某些寄存器做某种用途,例如除法指令idivl规定被除数在eax寄存器中,edx寄存器必须是0,而除数可以是任何寄存器中。计算结果的商数保存在eax寄存器中 阅读全文 »
posted @ 2018-04-07 15:49 刘-皇叔 阅读(1429) 评论(0) 推荐(0) 编辑
摘要:.section 就是汇编程序指令的一种, GNU 汇编程序提供了很多这样的指令(directive),这种指令都是以句点“.”为开头,后跟指令名(小写字母),在此,我们只介绍在内核源代码中出现的几个指令。 .ascii 语法: .ascii "string"... .ascii 表示零个或多个(用 阅读全文 »
posted @ 2018-04-07 15:47 刘-皇叔 阅读(3343) 评论(1) 推荐(1) 编辑
摘要:x86汇编一直存在两种不同的语法,在intel的官方文档中使用intel语法,Windows也使用intel语法,而UNIX平台的汇编器一直使用AT&T语法。 AT&T 和 Intel 汇编语言的语法区别主要体现在操作数前缀、赋值方向、间接寻址语法、操作码的后缀上,而就具体的指令而言,在同一平台上, 阅读全文 »
posted @ 2018-04-07 15:43 刘-皇叔 阅读(2288) 评论(0) 推荐(3) 编辑
摘要:在 Linux 源代码中,以.S(或.s)为扩展名的文件是包含汇编语言代码的文件。 在 Linux 下有两种方式,一种是使用汇编程序 GAS 和连接程序 LD, 一种是使用 GCC。 GAS 把汇编语言源文件(.S 或.s)转换为目标文件(.o): 一旦创建了一个目标文件,就需要把它连接并执行,连接 阅读全文 »
posted @ 2018-04-07 15:39 刘-皇叔 阅读(1434) 评论(0) 推荐(0) 编辑
摘要:现代计算机都把存储器分成若干级,称为Memory Hierarchy,按照离CPU由近到远的顺序依次是CPU寄存器、 Cache、内存、硬盘,越靠近CPU的存储器容量越小但访问速度越快,下图给出了各种存储器的容量和访问速度的典型值: 寄存器、 Cache和内存中的数据都是掉电丢失的,这称为易失性存储 阅读全文 »
posted @ 2018-04-07 15:23 刘-皇叔 阅读(2078) 评论(0) 推荐(0) 编辑
摘要:现代操作系统普遍采用虚拟内存管理(Virtual Memory Management)机制,这需要MMU(Memory Management Unit,内存管理单元) 的支持。有些嵌入式处理器没有MMU,则不能运行依赖于虚拟内存管理的操作系统。 虚拟地址和物理地址 首先引入两个概念,虚拟地址和物理地 阅读全文 »
posted @ 2018-04-07 15:17 刘-皇叔 阅读(701) 评论(0) 推荐(0) 编辑
摘要:CPU执行指令除了访问内存之外还要访问很多设备( Device) ,如键盘、鼠标、硬盘、显示器等,它们和CPU之间的连接: 有些设备像内存芯片一样连接到处理器的地址总线和数据总线,正因为地址线和数据线上可以挂多个设备和内存芯片所以才叫“总线”,但不同的设备和内存应该占不同的地址范围。访问这种设备就像 阅读全文 »
posted @ 2018-04-07 15:01 刘-皇叔 阅读(207) 评论(0) 推荐(0) 编辑
摘要:CPU总是周而复始地做同一件事:从内存取指令,然后解释执行它,然后再取下一条指令,再解释执行。 CPU包含以下功能单元: 寄存器(Register),是CPU内部的高速存储器,像内存一样可以存取数据,但比访问内存快得多。 程序计数器(PC,Program Counter,保存着CPU取指令的地址,每 阅读全文 »
posted @ 2018-04-07 14:48 刘-皇叔 阅读(215) 评论(0) 推荐(0) 编辑
摘要:现代计算机都是基于Von Neumann体系结构的,不管是嵌入式系统、 PC还是服务器。这种体系结构的主要特点是: CPU(CPU, Central Processing Unit,中央处理器,或简称处理器Processor) 和内存(Memory) 是计算机的两个主要组成部分,内存中保存着数据和指 阅读全文 »
posted @ 2018-04-07 14:38 刘-皇叔 阅读(499) 评论(0) 推荐(0) 编辑
摘要:Side Effect 改变计算机存储单元里的数据或者做输入或输出操作,这些都算Side Effect。 比如: int a = 10; /* a这个表达式在这里没有副作用,这里只是想要取得a这个变量的值10 */ int b = a; /*,而b = a这个表达式有副作用,它的副作用是使b的值改变 阅读全文 »
posted @ 2018-04-07 14:31 刘-皇叔 阅读(201) 评论(0) 推荐(0) 编辑
摘要:&& 逻辑与 使用格式:条件A && 条件B; 运算结果: 只有当条件A和条件B都成立时,结果才为1,也就是“真”;其余情况的结果都为0,也就是“假”。因此,条件A或条件B只要有一个不成立,结果都为0,也就是“假” 运算过程: 总是先判断条件A是否成立,如果条件A成立,接着再判断条件B是否成立:如果 阅读全文 »
posted @ 2018-04-07 12:02 刘-皇叔 阅读(7294) 评论(0) 推荐(0) 编辑
摘要:在两种类型之间做转换,转换结果将取决于两种类型的精度: 1. 精度是N的有符号整数类型应该用N个Bit表示,取值范围至少应该覆盖(-2N-1, 2N-1)。例如signed char型用8个Bit表示,表示的取值范围是[-128, 127],也可以说是覆盖了(-128, 128),所以这种类型的精度 阅读全文 »
posted @ 2018-04-07 11:35 刘-皇叔 阅读(590) 评论(0) 推荐(0) 编辑
摘要:Integer Promotion 在一个表达式中,凡是可以使用int或unsigned int类型做右值的地方也都可以使用有符号或无符号的char型、 short型和Bit-field。如果原始类型的取值范围都能用int型表示,则其值被提升为int型,如果表示不了就提升为unsigned int型 阅读全文 »
posted @ 2018-04-07 11:02 刘-皇叔 阅读(283) 评论(0) 推荐(0) 编辑
摘要:C标准规定的浮点型有float、 double、 long double,和整数类型一样,既没有规定每种类型占多少字节,也没有规定采用哪种表示形式。浮点数的实现在各种平台上差异很大,有的处理器有浮点运算单元(称为硬件实现),有的处理器没有,只能做整数运算,那么就要用整数运算来模拟浮点运算(称为软件实 阅读全文 »
posted @ 2018-04-07 10:31 刘-皇叔 阅读(1868) 评论(0) 推荐(0) 编辑
摘要:char 计算机存储的最小单位是字节( Byte) ,一个字节通常是8个bit。 C语言规定char型占一个字节的存储空间。 如果这8个bit按无符号整数来解释,则取值范围是0~255,如果按有符号整数来解释,则取值范围是-128~127。 C语言规定了signed和unsigned两个关键字, u 阅读全文 »
posted @ 2018-04-07 10:19 刘-皇叔 阅读(950) 评论(0) 推荐(0) 编辑
摘要:atoi atoi把一个字符串开头可以识别成十进制整数的部分转换成int型 。 例如: atof atof把一个字符串开头可以识别成浮点数的部分转换成double型。 字符串开头可以识别的浮点数格式和C语言的浮点数常量相同: strtol strtol是atoi的增强版,主要体现在这几方面: 不仅可 阅读全文 »
posted @ 2018-04-06 22:25 刘-皇叔 阅读(1995) 评论(0) 推荐(0) 编辑
摘要:stdio .h 头文件定义了三个变量类型、一些宏和各种函数来执行输入和输出。 库变量 下面是头文件 stdio.h 中定义的变量类型: 变量 描述 size_t 这是无符号整数类型,它是 sizeof 关键字的结果。 FILE 这是一个适合存储文件流信息的对象类型。 fpos_t 这是一个适合存储 阅读全文 »
posted @ 2018-04-05 18:33 刘-皇叔 阅读(228) 评论(0) 推荐(0) 编辑
摘要:stddef .h 头文件定义了各种变量类型和宏。这些定义中的大部分也出现在其它头文件中。 库变量 下面是头文件 stddef.h 中定义的变量类型: 变量 描述 ptrdiff_t 这是有符号整数类型,它是两个指针相减的结果。 size_t 这是无符号整数类型,它是 sizeof 关键字的结果。 阅读全文 »
posted @ 2018-04-05 18:30 刘-皇叔 阅读(168) 评论(0) 推荐(0) 编辑
摘要:limits.h 头文件决定了各种变量类型的各种属性。定义在该头文件中的宏限制了各种变量类型(比如 char、int 和 long)的值。 这些限制指定了变量不能存储任何超出这些限制的值,例如一个无符号可以存储的最大值是 255。 库宏 下面的值是特定实现的,且是通过 #define 指令来定义的, 阅读全文 »
posted @ 2018-04-05 18:29 刘-皇叔 阅读(194) 评论(0) 推荐(0) 编辑
摘要:C 标准库的 float.h 头文件包含了一组与浮点值相关的依赖于平台的常量。这些常量是由 ANSI C 提出的,这让程序更具有可移植性。在讲解这些常量之前,最好先弄清楚浮点数是由下面四个元素组成的: 组件 组件描述 S 符号 ( +/- ) b 指数表示的基数,2 表示二进制,10 表示十进制,1 阅读全文 »
posted @ 2018-04-05 18:25 刘-皇叔 阅读(321) 评论(0) 推荐(0) 编辑
摘要:C 标准库的 errno.h 头文件定义了整数变量 errno,它是通过系统调用设置的,在错误事件中的某些库函数表明了什么发生了错误。该宏扩展为类型为 int 的可更改的左值,因此它可以被一个程序读取和修改。 在程序启动时,errno 设置为零,C 标准库中的特定函数修改它的值为一些非零值以表示某些 阅读全文 »
posted @ 2018-04-05 18:21 刘-皇叔 阅读(154) 评论(0) 推荐(0) 编辑
摘要:C 标准库的 ctype.h 头文件提供了一些函数,可用于测试和映射字符。 这些函数接受 int 作为参数,它的值必须是 EOF 或表示为一个无符号字符。 如果参数 c 满足描述的条件,则这些函数返回非零(true)。如果参数 c 不满足描述的条件,则这些函数返回零。 库函数 标准库还包含了两个转换 阅读全文 »
posted @ 2018-04-05 17:53 刘-皇叔 阅读(110) 评论(0) 推荐(0) 编辑
摘要:string .h 头文件定义了一个变量类型、一个宏和各种操作字符数组的函数。 库变量 下面是头文件 string.h 中定义的变量类型: 变量 描述 size_t 这是无符号整数类型,它是 sizeof 关键字的结果。 库宏 下面是头文件 string.h 中定义的宏: 宏 描述 NULL 这个宏 阅读全文 »
posted @ 2018-04-05 17:52 刘-皇叔 阅读(169) 评论(0) 推荐(0) 编辑
摘要:locale.h 头文件定义了特定地域的设置,比如日期格式和货币符号。接下来我们将介绍一些宏,以及一个重要的结构 struct lconv 和两个重要的函数。 库宏 下面列出了头文件 locale.h 中定义的宏: 宏 描述 LC_ALL 设置下面的所有选项。 LC_COLLATE 影响 strco 阅读全文 »
posted @ 2018-04-05 17:51 刘-皇叔 阅读(196) 评论(0) 推荐(0) 编辑
摘要:C 标准库的 assert.h头文件提供了一个名为 assert 的宏,它可用于验证程序做出的假设,并在假设为假时输出诊断消息。 已定义的宏 assert 指向另一个宏 NDEBUG,宏 NDEBUG 不是 <assert.h> 的一部分。如果已在引用 <assert.h> 的源文件中定义 NDEB 阅读全文 »
posted @ 2018-04-05 17:49 刘-皇叔 阅读(201) 评论(0) 推荐(0) 编辑
摘要:stdarg.h 头文件定义了一个变量类型 va_list 和三个宏,这三个宏可用于在参数个数未知(即参数个数可变)时获取函数中的参数。 可变参数的函数通在参数列表的末尾是使用省略号(,...)定义的。 库变量 下面是头文件 stdarg.h 中定义的变量类型: 变量 描述 va_list 这是一个 阅读全文 »
posted @ 2018-04-05 17:48 刘-皇叔 阅读(119) 评论(0) 推荐(0) 编辑
摘要:signal.h 头文件定义了一个变量类型 sig_atomic_t、两个函数调用和一些宏来处理程序执行期间报告的不同信号。 库变量 下面是头文件 signal.h 中定义的变量类型: 变量 描述 sig_atomic_t 这是 int 类型,在信号处理程序中作为变量使用。它是一个对象的整数类型,该 阅读全文 »
posted @ 2018-04-05 17:47 刘-皇叔 阅读(163) 评论(0) 推荐(0) 编辑
摘要:setjmp.h 头文件定义了宏 setjmp()、函数 longjmp() 和变量类型 jmp_buf,该变量类型会绕过正常的函数调用和返回规则。 库变量 下面列出了头文件 setjmp.h 中定义的变量: 变量 描述 jmp_buf 这是一个用于存储宏 setjmp() 和函数 longjmp( 阅读全文 »
posted @ 2018-04-05 17:46 刘-皇叔 阅读(120) 评论(0) 推荐(0) 编辑
摘要:time.h 头文件定义了四个变量类型、两个宏和各种操作日期和时间的函数。 库变量 下面是头文件 time.h 中定义的变量类型: 变量 描述 size_t 这是无符号整数类型,它是 sizeof 关键字的结果。 clock_t 这是一个适合存储处理器时间的类型。 time_t 这是一个适合存储日历 阅读全文 »
posted @ 2018-04-05 17:44 刘-皇叔 阅读(124) 评论(0) 推荐(0) 编辑
摘要:math.h 头文件定义了各种数学函数和一个宏。在这个库中所有可用的功能都带有一个 double 类型的参数,且都返回 double类型的结果。 库宏 下面是这个库中定义的唯一的一个宏: 宏 描述 HUGE_VAL 当函数的结果不可以表示为浮点数时。如果是因为结果的幅度太大以致于无法表示,则函数会设 阅读全文 »
posted @ 2018-04-05 17:42 刘-皇叔 阅读(156) 评论(0) 推荐(0) 编辑
摘要:stdlib .h 头文件定义了四个变量类型、一些宏和各种通用工具函数。 库变量 下面是头文件 stdlib.h 中定义的变量类型: 变量 描述 size_t 这是无符号整数类型,它是 sizeof 关键字的结果。 wchar_t 这是一个宽字符常量大小的整数类型。 div_t 这是 div 函数返 阅读全文 »
posted @ 2018-04-05 17:38 刘-皇叔 阅读(197) 评论(0) 推荐(0) 编辑
摘要:改变缓冲方式 只有当指定的流被打开但还没有在它上面执行任何其他操作前才能被调用。 setbuf设置另一个长度为BUFSIZ(stdio.h)的字符数组对流进行缓冲。如果用一个NULL参数调用,setbuf将关闭流的所有缓冲方式。 如果在流关闭之前,程序的执行离开了数组声明所在的代码块,流就会继续使用 阅读全文 »
posted @ 2018-04-05 17:33 刘-皇叔 阅读(108) 评论(0) 推荐(0) 编辑
摘要:二进制I/O 把数据写入到文件效率最高的方法是用二进制形式写入。二进制输出避免了在 数值转换为字符串过程中涉及的开销和精度损失。 fread函数用于读取二进制数据,fwrite用于写入二进制数据。 buffer是一个指向用于保存数据的内存位置的指针,size是缓冲区中每个元素的字节数,count是读 阅读全文 »
posted @ 2018-04-05 17:31 刘-皇叔 阅读(422) 评论(0) 推荐(0) 编辑
摘要:未格式化的行I/O fgets从指定的文件中读一行字符到调用者提供的缓冲区中, gets从标准输入读一行字符到调用者提供的缓冲区中。 gets函数的存在只是为了兼容以前的程序,我们写的代码都不应该调用这个函数。 gets函数的接口设计得很有问题,就像strcpy一样,用户提供一个缓冲区,却不能指定缓 阅读全文 »
posted @ 2018-04-05 17:19 刘-皇叔 阅读(330) 评论(0) 推荐(0) 编辑
摘要:字符I/O 字符输入是由getchar家族执行的,原型如下: fgetc函数从指定的文件中读一个字节, getchar从标准输入读一个字节,调用getchar()相当于调用fgetc(stdin)。 需要操作的流作为参数传给getc和fgetc,但getchar始终从标准输入读取。每个函数从流读取一 阅读全文 »
posted @ 2018-04-05 17:16 刘-皇叔 阅读(227) 评论(0) 推荐(0) 编辑
摘要:文件I/O的一般情况 1.程序必须为同时处于活动状态的每个文件声明一个指针变量,其类型为FILE*。这个指针指向FILE结构,当它处于活动状态时由流使用。 2.流通过调用fopen函数打开,为了打开一个流,必须指定需要访问的文件或设备以及它们的访问方式(例如:读,写,既读又写)。fopen和操作系统 阅读全文 »
posted @ 2018-04-05 16:55 刘-皇叔 阅读(227) 评论(0) 推荐(0) 编辑
摘要:流 就C程序而言,所有的I/O操作只是简单地从程序移进或移出字节的事情。因此,毫不惊奇的是,这种字节流便被称为流(stream)。程序只需要关心创建正确的输出字节数据,以及正确地解释从输入读取的字节数据。特定I/O设备的细节对程序员是隐藏的。 简单地说,流是对信息的一种抽象。C系统在处理文件(文本文 阅读全文 »
posted @ 2018-04-05 16:53 刘-皇叔 阅读(525) 评论(0) 推荐(0) 编辑
摘要:错误报告 errno errno定义在<errno.h>头文件中,外部变量errno保存库程序中实现定义的错误码,通常被定义为errno.h中以E开头的宏,所有错误码都是正整数。 在linux中使用c语言编程时,errno很有用的。他可以把最后一次调用c的方法的错误代码保留。但是如果最后一次成功的调 阅读全文 »
posted @ 2018-04-05 16:49 刘-皇叔 阅读(243) 评论(0) 推荐(0) 编辑
摘要:#error #error指令使预处理器发出一条错误消息,然后停止执行预处理。#error 一般形式为#error info,如#error MFC requires C++ compilation。 #line #line指令用于重新设定当前由__FILE__和__LINE__宏指定的源文件名字和 阅读全文 »
posted @ 2018-04-05 16:25 刘-皇叔 阅读(170) 评论(0) 推荐(0) 编辑
摘要:条件编译 一般情况下,在进行编译时对源程序中的每一行都要编译,但是有时希望程序中某一部分内容只在满足一定条件时才进行编译,如果不满足这个条件,就不编译这部分内容,这就是条件编译。 条件编译主要是进行编译时进行有选择的挑选,注释掉一些指定的代码,以达到多个版本控制、防止对文件重复包含的功能。#if,# 阅读全文 »
posted @ 2018-04-05 16:23 刘-皇叔 阅读(589) 评论(0) 推荐(0) 编辑
摘要:预处理器在源码编译之前进行的一些文本性质的操作,它的主要任务包括删除注释,插入被#include指令包含的文件内容,定义和替换由#define指令定义的符号以及确定代码的部分内容是否应该根据一些条件编译指令进行编译。 预定义符号 __DATE__,字符串常量类型,表示当前所在源文件的编译日期,输出格 阅读全文 »
posted @ 2018-04-05 16:20 刘-皇叔 阅读(465) 评论(0) 推荐(0) 编辑
摘要:联合体 当多个数据需要共享内存或者多个数据每次只取其一时,可以利用联合体(union)。 它的所有成员相对于基地址的偏移量都为0。 此结构空间要大到足够容纳最"宽"的成员。 其对齐方式要适合其中所有的成员。 联合的初始化 联合变量初始化时,这个初始值必须是联合的第1个成员的类型,而且必须是位于一对花 阅读全文 »
posted @ 2018-04-05 16:14 刘-皇叔 阅读(140) 评论(0) 推荐(0) 编辑
摘要:位段(bit-field)是以位为单位来定义结构体(或联合体)中的成员变量所占的空间。含有位段的结构体(联合体)称为位段结构。采用位段结构既能够节省空间,又方便于操作。 位段的定义格式为: type [var]: digits 其中type只能为int,unsigned int,signed int 阅读全文 »
posted @ 2018-04-05 16:12 刘-皇叔 阅读(275) 评论(0) 推荐(0) 编辑
摘要:结构的初始化 结构的初始化与数组的初始化类似,一个位于一对花括号内部、由逗号分隔的初始值列表可用于结构各个成员的初始化。这些值根据结果成员列表写出。如果初始化列表的值不够,剩余的结构成员将使用缺省的值进行初始化。 例如: 结构体的存储分配 考虑下面的结构: 如果某个机器的整型值长度为4个字节,并且它 阅读全文 »
posted @ 2018-04-05 16:09 刘-皇叔 阅读(164) 评论(0) 推荐(0) 编辑
摘要:结构 聚合类型能够同时存储超过一个的单独数据,C提供了两种类型的聚合数据类型,数组和结构。数组是相同类型的元素的集合,它的每个元素是通过下标引用或指针间接访问来选择的。结构也是一些值的集合,这些值称为它的成员。但一个结构的各个成员可能具有不同的类型。 数组元素可以通过下标来访问,这是因为数组元素的长 阅读全文 »
posted @ 2018-04-05 16:00 刘-皇叔 阅读(535) 评论(0) 推荐(0) 编辑
摘要:字符串函数在处理字符串的时候,遇到NUL就会停止,但是非字符串中有很多包含NUL的情况,那个就用到了上面的函数了。memcpy 实现的就是将 src 的数据 length 个复制到 dst 中,同时如果是整型或浮点数组,那么也不用进行强制转换,因为函数的参数是void的类型指针,所有类型的指针都可以 阅读全文 »
posted @ 2018-04-05 13:27 刘-皇叔 阅读(118) 评论(0) 推荐(0) 编辑
摘要:字符分类相关函数 ctype.h提供了如下字符处理函数; 字符转换 如果传入的参数不需要进行操作或无法进行操作,不进行修改参数直接返回。 阅读全文 »
posted @ 2018-04-05 13:26 刘-皇叔 阅读(102) 评论(0) 推荐(0) 编辑
摘要:strerror 这个函数是 string.h 的头文件中定义的 它的函数原型是: 这个函数的参数是一个外部整型变量 errno ,在你调用函数出现错误的时候就会通过 errno 这个变量作为 strerror 的参数,并返回一个指向描述错误的字符串的指针。 输出: 阅读全文 »
posted @ 2018-04-05 13:25 刘-皇叔 阅读(176) 评论(0) 推荐(0) 编辑
摘要:查找一个字符 strchr和strrchr 函数是 string.h 的头文件中定义的 它们的函数原型是 : strchr 功能是返回字符第一次出现在字符串中的位置,strrchr 的功能是返回最后一次出现字符串中的位置。如果不存在返回NULL指针。 查找任何几个字符 strpbrk 这个函数是 s 阅读全文 »
posted @ 2018-04-05 13:23 刘-皇叔 阅读(138) 评论(0) 推荐(0) 编辑
摘要:字符串就是一串零个或多个字符,并且以一个位模式为全0的NULL字节结尾,因此,字符串所包含的字符内部不能出现NULL,NULL是字符串的终止符,但并不是字符串的一部分,所以字符串的长度不包含NULL。 给字符串赋初值 memset函数把s所指的内存地址开始的n个字节都填充为c的值。 例如使用mall 阅读全文 »
posted @ 2018-04-05 13:20 刘-皇叔 阅读(644) 评论(0) 推荐(0) 编辑
摘要:指针数组 []优先级高,先与p结合成为一个数组,再由int*说明这是一个整型指针数组,它有n个指针类型的数组元素。 注意: 执行p+1,则p指向下一个数组元素。 如要将二维数组赋给一指针数组: 这里int *p[3] 表示一个一维数组内存放着三个指针变量,分别是p[0]、p[1]、p[2],所以要分 阅读全文 »
posted @ 2018-04-05 13:09 刘-皇叔 阅读(152) 评论(0) 推荐(0) 编辑
摘要:存储顺序 在C语言中,多维数组的元素存储顺序是按照最右边的下标率先变化的原则,称为行主序。例如:a[3][6] 元素的下标值分别为:0,0 0,1 0,2 0,3 0,4 0,5 1,0 1,1 1,2 1,3 1,4 1,5 2,0 2,1 2,2 2,3 2,4 2,5 数组名 一维数组名的值是 阅读全文 »
posted @ 2018-04-05 12:44 刘-皇叔 阅读(401) 评论(0) 推荐(0) 编辑
摘要:初始化 给数组赋值的方法除了用赋值语句对数组元素逐个赋值外, 还可采用初始化赋值和动态赋值的方法。数组初始化赋值是指在数组定义时给数组元素赋予初值。数组初始化是在编译阶段进行的。这样将减少运行时间,提高效率。初始化赋值的一般形式为:类型说明符 数组名[常量表达式] = { 值, 值……值 };其中在 阅读全文 »
posted @ 2018-04-05 12:41 刘-皇叔 阅读(737) 评论(0) 推荐(0) 编辑
摘要:数组和指针 声明一个数组时,编译器将根据声明所指定的元素数量为为数组保留内存空间,然后再创建数组名,它的值是一个常量,指向这段空间的起始位置。 声明一个指针变量时,编译器只为指针本身保留内存空间,它并不为任何整型值分配内存空间。而且,指针变量并未被初始化为指向任何现有的内存空间,如果它是一个自动变量 阅读全文 »
posted @ 2018-04-05 12:37 刘-皇叔 阅读(372) 评论(0) 推荐(0) 编辑
摘要:C 语言支持数组数据结构,它可以存储一个固定大小的相同类型元素的顺序集合。 数组是用来存储一系列数据,但它往往被认为是一系列相同类型的变量。 数组名 几乎在所有使用数组名的表达式中,数组名的值是一个指针常量,也就是数组第一个元素的地址,它的类型取决于数组元素的类型,如果它们是int型,那么数组名的类 阅读全文 »
posted @ 2018-04-05 12:35 刘-皇叔 阅读(255) 评论(0) 推荐(0) 编辑
摘要:C通过运行时堆栈支持递归函数的实现,递归函数就是直接或者间接调用自身的函数。 递归函数追踪 追踪递归函数执行过程的关键是理解函数中所声明的变量是如何存储的:当函数被调用时,它的变量的空间创建于运行时堆栈上,以前调用的函数的变量扔保留在堆栈上,但它们被新函数的变量所覆盖,因此不能被访问。 递归函数每进 阅读全文 »
posted @ 2018-04-05 12:23 刘-皇叔 阅读(243) 评论(0) 推荐(0) 编辑
摘要:函数调用 创建 C 函数时,会定义函数做什么,然后通过调用函数来完成已定义的任务。 当程序调用函数时,程序控制权会转移给被调用的函数。被调用的函数执行已定义的任务,当函数的返回语句被执行时,或到达函数的结束括号时,会把程序控制权交还给主程序。 调用函数时,传递所需参数,如果函数返回一个值,则可以存储 阅读全文 »
posted @ 2018-04-05 12:20 刘-皇叔 阅读(570) 评论(0) 推荐(0) 编辑
摘要:C 函数简介 函数是一组一起执行一个任务的语句。每个 C 程序都至少有一个函数,即主函数 main() ,所有简单的程序都可以定义其他额外的函数。 可以把代码划分到不同的函数中。但在逻辑上,划分通常是根据每个函数执行一个特定的任务来进行的。 函数声明告诉编译器函数的名称、返回类型和参数。函数定义提供 阅读全文 »
posted @ 2018-04-05 12:17 刘-皇叔 阅读(847) 评论(0) 推荐(0) 编辑
摘要:当一个字符串常量出现于表达式中,它的值是一个指针常量,编译器把这些指定字符的一份拷贝存储在内存中的某个位置,并存储一个指向第一个字符的指针,可以使用指针表达式也可以使用下标来使用字符串常量。 如下面的表达式: 这个表达式计算的是指针值加上1的值,结果是个指针,指向字符串中的第2个字符:y。 下面这个 阅读全文 »
posted @ 2018-04-05 12:11 刘-皇叔 阅读(287) 评论(0) 推荐(0) 编辑
摘要:函数指针初始化及使用函数指针调用函数 最常见的两个用途是转换表和作为参数传递给另外一个函数。 简单声明一个函数指针并不意味着可以马上使用,和其他指针一样,对函数指针执行间接访问之前必须把它初始化为指向某个函数。初始化方式: 这里的&是可选的,因为函数名被使用时总是由编译器将它转换成函数指针,&操作符 阅读全文 »
posted @ 2018-04-05 12:07 刘-皇叔 阅读(141) 评论(0) 推荐(0) 编辑
摘要:int f;/*声明一个整数*/ int *f;/*声明一个指向整型的指针*/ int *f,g;/*这个并不是两个整形指针,而是一个指针,一个整型*/ int f();/*一个返回值为整型的函数*/ int *f();/*本质是一个函数,函数的返回值为指向整型的指针*/ int (*f) ();/*本质是一个指针,指针指向一个返回值为整型的函数*/ int *(*f) ();/*本质是一个指... 阅读全文 »
posted @ 2018-04-05 12:02 刘-皇叔 阅读(211) 评论(0) 推荐(0) 编辑
摘要:变量的直接引用与间接引用 通过变量名叫做直接引用,通过指针对变量的引用叫间接引用 间接引用的两种情况: 如果在一个指针变量中存放的是一个目标变量的地址叫做一级地址。 如果在一个指针变量中存放的是指向目标变量的地址的指针变量的地址,那么这个就叫做二级地址。 指针的指针 如果一个指针指向的是另外一个指针 阅读全文 »
posted @ 2018-04-05 11:57 刘-皇叔 阅读(192) 评论(0) 推荐(0) 编辑
摘要:指针变量可以进行某些运算,但其运算的种类是有限的。 它只能进行赋值运算和部分算术运算及关系运算。 指针运算符 (1)取地址运算符&取地址运算符&是单目运算符,其结合性为自右至左,其功能是取变量的地址。 (2)取内容运算符* 取内容运算符*是单目运算符,其结合性为自右至左,用来表示指针变量所指的变量。 阅读全文 »
posted @ 2018-04-05 11:55 刘-皇叔 阅读(606) 评论(0) 推荐(0) 编辑
摘要:指针变量的类型说明 对指针变量的类型说明包括三个内容:(1)指针类型说明,即定义变量为一个指针变量;(2)指针变量名;(3)变量值(指针)所指向的变量的数据类型。 其一般形式为: 类型说明符 *变量名;其中,*表示这是一个指针变量,变量名即为定义的指针变量名,类型说明符表示本指针变量所指向的变量的数 阅读全文 »
posted @ 2018-04-05 10:47 刘-皇叔 阅读(4072) 评论(0) 推荐(0) 编辑
摘要:内存和地址 所有的数据都是存放在存储器中的, 一般把存储器中的一个字节称为一个内存单元,不同的数据类型所占用的内存单元数不等。 为了正确地访问这些内存单元, 必须为每个内存单元编上号, 根据一个内存单元的编号即可准确地找到该内存单元。内存单元的编号也叫做地址。 既然根据内存单元的编号或地址就可以找到 阅读全文 »
posted @ 2018-04-05 10:40 刘-皇叔 阅读(447) 评论(0) 推荐(0) 编辑
摘要:求字节运算符(sizeof) sizeof()的作用是用来计算一个变量或者一个常量、一种数据类型所占的内存字节数。 基本形式: sizeof有两种形式: sizeof 表达式和sizeof(类型名)。 sizeof 表达式中的表达式并不求值,只是根据类型转换规则求得该表达式的类型,然后把这种类型所占 阅读全文 »
posted @ 2018-04-05 10:28 刘-皇叔 阅读(308) 评论(0) 推荐(0) 编辑
摘要:条件运算符 条件运算符是唯一的一个三目运算符 格式:(条件判断)?操作1:操作2 作用: 如果条件表达式为真,则执行操作1,条件表达式为假,则执行操作2 优先级: 条件运算符高于赋值运算符,但低于逻辑运算符、关系运算符和算术运算符 例:int a = 5?10:2; 获得a、b中的最大数 获得a、b 阅读全文 »
posted @ 2018-04-05 10:22 刘-皇叔 阅读(910) 评论(0) 推荐(0) 编辑
摘要:指针运算符 &取地址运算符,求得某个变量地址 *指针运算符,求得所指地址的空间里的值 赋值运算符和赋值表达式 C语言中,“=”称作赋值运算符,作用是将一个数值赋给一个变量或将一个变量的值赋给另一个变量,由赋值运算符组成的表达式称为赋值表达式。 简单赋值: 一般形式:变量名=表达式 注意: 在程序中可 阅读全文 »
posted @ 2018-04-05 10:20 刘-皇叔 阅读(1232) 评论(0) 推荐(0) 编辑
摘要:基本的位运算符 & 按位与,规则:若两个相应额二进制位都为1,则该位的结果为1,否则为0 | 按位或,规则:两个相应的二进制位中只要有一个为1,则该位的结果为1,否则为0 ^ 按位异或,规则:若两个二进制位相同,则结果为0,不同则为1 ~ 按位求反,规则:安慰取反,即0变1,1变0 << 左移 >> 阅读全文 »
posted @ 2018-04-05 10:13 刘-皇叔 阅读(327) 评论(0) 推荐(1) 编辑
摘要:算术运算符和算术表达式 基本的算数运算符 + 加法运算 - 减法运算 * 乘法运算 / 除法运算 % 取余运算 注意: %两侧只能是整数,正负性取决于%左侧的数值 整数和整数运算,结果是整数,尤其是在使用除法时需要注意会舍去小数部分 算术表达式 算术表达式是用算术运算符和括号将运算量(也称操作数)连 阅读全文 »
posted @ 2018-04-05 09:59 刘-皇叔 阅读(957) 评论(0) 推荐(0) 编辑
摘要:操作符分类 C语言一共有34种运算符,共计10种运算类型: 若按参与运算的对象个数,C语言运算符可分为: 单目运算符、双目运算符、和三目运算符。 运算符的结合性和优先级 运算符的结合性 在C语言的运算符中,所有的单目运算符、条件运算符、赋值运算符及其扩展运算符,结合方向都是从右向左,其余运算符的结合 阅读全文 »
posted @ 2018-04-05 09:54 刘-皇叔 阅读(503) 评论(0) 推荐(0) 编辑
摘要:break语句 (1) 只能在循环体内和switch语句体内使用break语句。 (2) 当break出现在循环体中的switch语句体内时,其作用只是跳出该switch语句体。 (3) 当break出现在循环体中,但并不在switch语句体内时,则在执行break后,跳出本层循环体。 (4) 在循 阅读全文 »
posted @ 2018-04-05 09:31 刘-皇叔 阅读(751) 评论(0) 推荐(0) 编辑
摘要:每个循环(for循环或者while循环)都有一个共同的特点: 拥有循环初始化语句、循环执行的条件、使循环趋于结束的条件(称为调整语句)、循环体,下面结合实际的循环简要分析下: for循环 其中的statement称为循环体;exp1是循环初始化语句;exp2为循环执行要满足的条件;exp3为使循环趋 阅读全文 »
posted @ 2018-04-05 09:26 刘-皇叔 阅读(222) 评论(0) 推荐(0) 编辑
摘要:if语句 形式: 含义: 上述代码中,cond表示条件,它的值可以是任何能够产生整型结果的表达式:零值表示“假”,非零值表示“真”;statement1和statement2表示代码块。 注意C中没有布尔类型,因而是用整型来代替判断条件。 注意: 当if语句嵌套时,就会出现else悬空的情况,这时候 阅读全文 »
posted @ 2018-04-05 09:21 刘-皇叔 阅读(286) 评论(0) 推荐(0) 编辑
摘要:程序语句从大的方向来划分,只有三种: 顺序执行语句、分支语句(跳过部分执行)、循环语句(往复执行)。 空语句 C语言中最简单的语句就是空语句,它由分号“;”构成。空语句本身不执行任何操作,但也有它存在的价值。它适用的情况是语法要求出现一条完整的语句,但是并不需要它执行任何的任务。 某些情况下,它的存 阅读全文 »
posted @ 2018-04-05 09:16 刘-皇叔 阅读(1370) 评论(0) 推荐(0) 编辑
摘要:typedef为C语言的关键字,作用是为一种数据类型定义一个新名字。这里的数据类型包括内部数据类型(int,char等)和自定义数据类型。 与#define的区别 定义一种类型的别名,而不只是简单的宏替换。可以用作同时声明指针型的多个对象。比如: 以下则可行: 简化struct声明 以前的代码中,声 阅读全文 »
posted @ 2018-04-05 09:06 刘-皇叔 阅读(117) 评论(0) 推荐(0) 编辑
摘要:C 字面值 常量是固定值,在程序执行期间不会改变。这些固定的值,又叫做字面量。 常量可以是任何的基本数据类型,比如整数常量、浮点常量、字符常量,或字符串字面值,也有枚举常量。 常量就像是常规的变量,只不过常量的值在定义后不能进行修改。 整数字面值 整数常量可以是十进制、八进制或十六进制的常量。前缀指 阅读全文 »
posted @ 2018-04-05 08:56 刘-皇叔 阅读(606) 评论(0) 推荐(0) 编辑
摘要:变量的定义 变量定义就是告诉编译器在何处创建变量的存储,以及如何创建变量的存储。变量定义指定一个数据类型,并包含了该类型的一个或多个变量的列表,如下所示: type variable_list; 在这里,type 必须是一个有效的 C 数据类型,可以是 char、w_char、int、float、d 阅读全文 »
posted @ 2018-04-05 08:45 刘-皇叔 阅读(8612) 评论(0) 推荐(1) 编辑
摘要:void 类型指定没有可用的值。它通常用于以下三种情况下: 类型 描述 函数返回为空 C 中有各种函数都不返回值,或者您可以说它们返回空。不返回值的函数的返回类型为空。例如 void exit (int status); 函数参数为空 C 中有各种函数不接受任何参数。不带参数的函数可以接受一个 vo 阅读全文 »
posted @ 2018-04-05 08:27 刘-皇叔 阅读(266) 评论(0) 推荐(0) 编辑

点击右上角即可分享
微信分享提示