自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(225)
  • 收藏
  • 关注

原创 c语言深度剖析(26)—指针的本质分析

程序中的变量只是一段存储空间的别名,那么是不是必须通过这个别名才能使用这段存储空间? 问题:程序中的变量只是一段存储空间的别名,那么是不是必须通过这个别名才能使用这段存储空间? 问题:是不是只能通过变量使用存储空间?#include<stdio.h>int main(){ int i = 5; int *p = &i; printf("i = %d, p =...

2019-08-11 22:53:40 231

原创 c语言深度剖析(25)—#和##操作符使用分析

1.#运算符#运算符用于在预处理期将宏参数转换为字符串 #的转换作用是在预处理期完成的,因此只在宏定义中有效 编译器不知道#的转换作用 用法 :#define STRING(x)#xprintf("%s\n", STRING(Hello World!));#运算符的基本用法#include<stdio.h>#defineSTRING(...

2019-08-09 22:29:09 179

原创 c语言深度剖析(24)—#pragma使用分析、内存对齐

1.#pragma简介#pragma用于指示编译器完成一些特定的动作 #pragma所定义的很多指示字是编译器特有的 #pragma在不同的编译器间是不可移植的 预处理器将忽略它不认识的#pragma指令 不同的编译器可能以不同的方式解释同—条#pragma指令 一般用法:#pragma parameter,注:不同的parameter参数语法和意义各不相同2...

2019-08-09 15:43:16 398

原创 c语言深度剖析(23)—error和#line使用分析

1.#error的用法#error用于生成一个编译错误消息 用法:#error message,其中message不需要用双引号包围 #error编译指示字用于自定义程序员特有的编译错误消息,类似的,#warning用于生成编译警告 #error是一种预编译器指示字 #error可用于提示编译条件是否满足 编译过程中的任意错误信息意味着无法生成最终的可执行程序。2.编程实验...

2019-08-09 09:42:01 267

原创 c语言深度剖析(22)—条件编译使用分析

1.基本概念条件编译的行为类似于C语言中的if…else…; 条件编译是预编译指示命令,用于控制是否编译某段代码; 可以利用预处理器调整代码、删除代码的操作。2.编程实验条件编译初探//#include<stdio.h>#define C 1int main(){ const char* s;#if(1 == C) s = "this is fir...

2019-08-08 23:27:30 163

原创 c语言深度剖析(21)—宏定义的使用与分析

0.对于宏的第一印象:可以定义一个常量,如:#define PI 3.14159 可以定义一个代码块,将宏作为函数使用,如:# include <stdio.h>// 此处将交换两个变量的函数用宏来定义#define SWAP(a, b) \{ \ int temp = a; \ a =...

2019-08-08 17:08:34 308

原创 c语言深度剖析(20)—链接过程简介

1.链接器的意义每个C语言源文件被编译后生成目标文件,这些目标文件最终要被链接在一起生成可执行文件 链接器的主要作用是把各个模块之间相互引用的部分处理好,使得各个模块之间能够正确的衔接2.静态链接由链接器在链接时将库的内容直接加入到可执行程序中Linux下静态库的创建和使用 编译静态库源码: gcc -c lib.c -o lib.o 生成静态库文件: ar -...

2019-08-08 15:10:07 302

原创 c语言深度剖析(19)—编译过程简介

1.初始编译器2.预编译:指令示例——gcc –E file.c –o file.i处理所有的注释,以空格代替 将所有的#define删除,并且展开所有的宏定义 处理条件编译指令#if、#ifdef、#elif、#else、#endif 处理#include,展开被包含的文件 保留编译器需要使用的#pragma指令3.编译:指令示例——gcc –S file.i –o ...

2019-08-08 14:22:28 220

原创 c语言深度剖析(18)—三目运算符和逗号表达式

1.三目运算符三目运算符(a?b:c)可以作为逻辑运算的载体 规则:当a的值为真时,返回变量b的值(而不是变量本身);否则返回c的值。(c++中返回变量本身) 三目运算符(a?b:c)的返回类型 通过隐式类型转换规则返回b或c中较高的类型 当b和c不能隐式转换到同一类型时将编译出错 2.编程实验三目运算符初探#include <stdio.h>#inclu...

2019-08-08 11:19:26 503

原创 c语言深度剖析(17)—++和--操作符分析

1. ++和—操作符对应的两条汇编指令前置++或--:变量自增(减)1,然后取变量值 后置++或--:取变量值,然后变量自增(减)12.++,-- 操作符使用分析一对令人头疼的兄弟nti=0;(i++)+(i++)+(i++);(++i)+(++i)+(++i);#include <stdio.h>in...

2019-08-08 10:27:51 312

原创 c语言深度剖析(16)—位运算符分析

1.C语言中的位运算符位运算符直接对bit位进行操作,其效率最高2.左移和右移注意点左操作数必须为整型类型:char和short被隐式转换为int后进行移位操作 右操作数的范围必须为:[0,31],其他值属未定义行为,不同编译器处理不同。 左移运算符<< 将运算数的二进制位左移:规则为高位丢弃,低位补0 右移运算符>> 把运算数的二进制位右移:规...

2019-08-08 10:01:14 811

原创 c语言深度剖析(15)—逻辑运算符分析

1.有趣问题逻辑运算符&&,||和!真的很简单吗?#include <stdio.h>int main(){ int i = 0; int j = 0; int k = 0; // 等价于(true && ++i) ||(++j && ++k)可见整个表达式为或运算,从左向右进行...

2019-08-08 10:01:09 642

原创 c语言深度剖析(14)—单引号和双引号

1.单引号和双引号C语言中单引号用来表示字符字面量(是个数值) C语言中双引号用来表示字符串字面量(是个指针) 'a'表示字符字面量(97),在内存中占用1个字节,'a'+1表示'a'的ASCII码加1,即'b' "a"表示字符串字面量(是个指针),在内存中占2个字了,"a"+1表示指针运算,指向"a"的结束符"\0" 下面的程序片段合法吗?char *pl = 1;c...

2019-08-08 10:01:02 1237

原创 c语言深度剖析(13)—接续符和转义符

1.接续符的意义C语言中的接续符(\)是指示编译器行为的利器// 使用接续符的例子#in\clud\e <st\dio.h>in\t m\ain(\){pri\ntf\ (\ "Hello World!\n" )\ ; ret\urn 0;}// 剔除接续符后的原码#include <stdio...

2019-08-08 10:00:40 656

原创 c语言深度剖析(12)—注释符号

1.似是而非的问题下面的注释是正确的吗?#include<stdio.h>int main(){ int/**/i; //合法int i; char* s = "abcdefg //ijklmn"; //合法引号内的双斜杠 //Is it a \ valid c...

2019-08-08 10:00:34 491

原创 c语言深度剖析(11)—enum、sizeof、typedef 分析

1. enum枚举类型1.1使用方法enum是C语言中的一种自定义类型 enum值是可以根据需要自定义的的整型值 第一个定义的enum值默认为0 默认情况下的enum值是在前一个定义值的基础上加1 enum类型的变量只能取定义时的离散值enum Color{ GREEN, // GREEN==0; RED= 2, // 自定义RED==2;...

2019-08-08 10:00:27 304

原创 c语言深度剖析(10)—struct和union分析

1.struct的小秘密C语言中的struct可以看作变量的集合 struct的问题:空结构体占用多大内存?#include <stdio.h>struct TS{};int main(){ struct TS t1; struct TS t2; // VC、BCC下定义空结构体编译器直接报错,gcc下空结构体大小为0 ...

2019-08-08 10:00:11 267

原创 c语言深度剖析(9)—const和volatile分析

1. const只读变量——(注意不是真正常量,只是告诉编译器不能出现在赋值号左边!)const修饰的变量是只读的,本质还是变量 const修饰的局部变量在栈上分配空间 const修饰的全局变量在全局数据区分配空间(vc、gcc会将其放入常量区,bcc放入全局数据区) const只在编译期有用(只能出现在赋值符号左边),在运行期无用#include <stdio.h>...

2019-08-06 14:23:27 253

原创 c语言深度剖析(8)—循环语句goto和void分析

1.遭人遗弃的goto高手潜规则:禁用goto 项目经验:程序质量与goto的出现次数成反比 最后的判决:将goto打入冷宫2.编程实验goto副作用分析#include <stdio.h>#include <stdlib.h>#include <malloc.h>void func(int n){ int *p = NULL;...

2019-08-06 14:23:20 258

原创 c语言深度剖析(7)—循环语句

1.循环语句分析循环语句的基本工作方式 ①通过条件表达式判定是否执行循环体 ②条件表达式遵循if语句表达式的原则 do、while、for的区别 ①do语句先执行后判断,循环体至少执行一次 ②while语句先判断后执行,循环体可能不被执行 ③for语句先判断后执行,相比while更简洁 2.循环的回顾do…while语句的循环方式while语句的循环方式...

2019-08-06 14:23:13 250

原创 c语言深度剖析(6)—分之语句

1. if语句if语句用于根据条件选择执行语句 else不能独立存在且总是与它之前最近的if相匹配 else语句后可以接连其他if语句if语句中零值比较的注意点 ①bool型变量直接出现于条件中,不要进行比较 ②变量和0值比较时,0值应该出现在比较符号左边 ③float型变量不能直接进行0值比较,需要定义精度 2.switch语句分析switch语句对应单个条件...

2019-08-06 14:23:06 193

原创 c语言深度剖析(5)—变量属性auto、register、static、extern

1.C语言的变量属性C语言中的变量可以有自己的属性 在定义变量的时候可以加上“属性”关键字 “属性”关键字指明变量的特有意义。语法:propertytypevar_name;如:auto char i; register int j; static long k; extern double m;2. auto关键字auto即C语言中局部变量的默认属...

2019-08-06 14:22:54 376

原创 c语言深度剖析(4)—类型转换

1. C语言中的类型之间的转换:强制类型转换和隐式类型的转换#include<stdio.h>int main(){ long l = 800; int i = (int)l; // 强制类型转换 short s = 800; int k = s; // 隐式类型转换,no error,no warning return 0;}...

2019-08-06 14:22:47 204

原创 c语言深度剖析(3)—浮点数的秘密

1.内存中的浮点数——存储方式:符号位、指数、尾数的符号float与double类型的数据在计算机内部的表示法是相同的,但由于所占存储空间不同,分别能够表示的数据值范围和精度不同。 解释:对于5.14 *10^11 : 14为尾数,11为指数,10为基2.浮点数的存储示例2.1浮点数的转换步骤将浮点数转换成二进制 用科学计数法表示二进制浮点数,十进制的整数部分转换为二...

2019-08-06 14:22:39 364

原创 无锁编程技术及实现

1.基于锁的编程的缺点多线程编程是多CPU系统在中应用最广泛的一种编程方式,在传统的多线程编程中,多线程之间一般用各种锁的机制来保证正确的对共享资源(shareresources)进行访问和操作。 在多线程编程中只要需要共享某些数据,就应当将对它的访问串行化。比如像++count(count是整型变量)这样的简单操作也得加锁,因为即便是增量操作这样的操作,,实际上也是分三步进行的:读、改、...

2019-08-05 14:34:34 1014

原创 C语言文件的编译与执行的四个阶段并分别描述

C语言的编译链接过程要把我们编写的一个c程序(源代码)转换成可以在硬件上运行的程序(可执行代码),需要进行编译和链接。编译就是把文本形式源代码翻译为机器语言形式的目标文件的过程。 链接是把目标文件、操作系统的启动代码和用到的库文件进行组织形成最终生成可执行代码的过程。过程图解如下:从图上可以看到,整个代码的编译过程分为编译和链接两个过程,编译对应图中的大括号括起的部分,其余则为链接过程...

2019-08-05 09:52:24 1223

原创 c语言字节对齐

0 引言考虑下面的结构体定义:typedef struct{ char c1; short s; char c2; int i;}T_FOO;假设这个结构体的成员在内存中是紧凑排列的,且c1的起始地址是0,则s的地址就是1,c2的地址是3,i的地址是4。 现在,我们编写一个简单的程序:#include <stdio.h>...

2019-08-03 21:09:23 170

原创 数据结构—希尔、快速、堆、归并排序

1.希尔排序希尔排序是希尔(Donald Shell)于1959年提出的一种排序算法。希尔排序也是一种插入排序,它是简单插入排序经过改进之后的一个更高效的版本,也称为缩小增量排序,同时该算法是冲破O(n2)的第一批算法之一。它与插入排序的不同之处在于,它会优先比较距离较远的元素。希尔排序又叫缩小增量排序。1.1 基本思想将待排序列划分为若干组,在每一组内进行插入排序,以使整个序列基本有序...

2019-08-02 15:06:44 742

原创 数据结构—选择、插入、冒泡排序

排序的分类排序的分类:排序分为插入排序、选择排序、交换排序、归并排序四大类,详细分类如下图:七大经典排序:冒泡排序、快速排序、选择排序、堆排序、插入排序、希尔排序、归并排序1.简单选择排序1.1 基本思想每一趟 (例如第 i 趟,i = 0, 1, …, n-2)在后面 n-i 个待排的数据元素中选出关键字最小的元素,作为有序元素序列的第 i 个元素。R[0..i]...

2019-08-01 22:54:39 266

原创 数据结构—排序的概念和分类

1.排序的一般定义排序是计算机内经常进行的一种操作,其目的是将一组“无序”的数据元素调整为“有序”的数据元素。 例如: 将下列关键字序列:52, 49, 80, 36, 14, 58, 61, 23, 97, 75 调整为:14, 23, 36, 49, 52, 58, 61 ,75, 80, 97 2.排序的数学定义假设含n个数据元素的序列为{ R1, R2, …, Rn}...

2019-08-01 16:01:04 938

原创 C++深度解析(48)—类模板深度剖析

1.多参数类模板类模板可以定义任意多个不同的类型参数template <typename T1,typename T2>class Test{public: void add(T1 a,T2 b);}​```Test<int,float> t;类模板可以被特化 指定类模板的特定实现,即特化是一个类模板其参数特殊情况时的分开实现 部分类...

2019-07-25 10:38:27 232

原创 C++深度解析(47)—类模板的概念和意义

1.类模板一些类主要用于存储和组织存数据元素 类中数据组织的方式和数据元素的具体类型无关。如数组类、链表类、Stack类、Queue类等。 C++中将模板的思想应用于类,使得类的实现不关注数据元素的具体类型,而只关注类所需要实现的功能。2.C++中的类模板以相同的方式处理不同的类型 在类声明前使用template进行标识 <typename T>用于说明类中使用的泛指...

2019-07-24 18:37:12 213

原创 C++深度解析(46)—深入理解函数模板

1.函数模板深入理解编译器从函数模板通过具体类型产生不同的函数 编译器会对函数模板进行两次编译 在声明的地方对模板代码本身进行编译 对参数替换后的代码进行编译(编译时机:可能发生在定义对象或函数调用时) 注意事项: 函数模板本身不允许隐式类型转换 自动推导类型时,必须严格匹配 显示类型指定时,能够进行隐式类型转换 编程实验:隐式类型转换问题#includ...

2019-07-24 15:51:03 227

原创 C++深度解析(45)—函数模板的概念和意义

1.发散性问题C++中有几种交换变量的方法?定义宏代码块 +定义函数2.编程实验定义宏代码块 VS 定义函数 #include <iostream>#include <string>using namespace std;// 宏定义代码块#define SWAP(t, a, b)\do...

2019-07-24 14:38:46 214

原创 C++深度解析(44)—被遗弃的多重继承(下)

1.多重继承的问题三多重继承可能产生多个虚函数表需要进行强制类型转换时,C++中推荐使用新式类型转换关键字!! 解决方案:dynamic_cast其中由于两个虚函数表内容几乎完全相同,所以强制类型转换后仍指向pa地址。 而使用dynamic_cast关键字时,编译器会自动进行调整,判断是否存在父类,并根据父类地址进行查找,从而避免了指针问题。2.编程实验多重继承问题...

2019-07-24 10:20:51 201

原创 C++深度解析(43)—被遗弃的多重继承(上)

1.C++中的多重继承C++支持编写多重继承的代码 一个子类可以拥有多个父类 子类拥有所有父类的成员变量 子类继承所有父类的成员函数 子类对象可以当作任意父类对象使用(父子类有赋值兼容性原则) 多重继承的语法规则class Derived : public BaseA,public BaseB,public BaseC{ //```` };多重继承的本质与...

2019-07-23 22:35:55 206

原创 C++深度解析(42)—C++中的抽象类和接口

1.什么是抽象类面向对象中的抽象概念 现实中:需要知道具体的图形类型,才能求面积。 Shape只是一个概念上的类型,没有具体对象2.面向对象中的抽象类可用于表示现实世界中的抽象概念 是一种只能定义类型,而不能产生对象的类 只能被继承并重写相关函数 直接特征是相关函数没有完整的实现3.抽象类与纯虚函数C++语言中没有抽象类的概念,它是通过纯虚函数实现抽象类,当一个C++类中...

2019-07-23 21:32:25 247

原创 C++深度解析(41)—C++对象模型分析(下)

1.继承对象模型在C++编译器的内部类可以理解为结构体 子类是由父类成员叠加子类新成员得到的编程实验——继承对象模型初探#include<iostream>using namespace std;class Demo{protected: int mi; int mj;public: void print() { cout << "...

2019-07-23 20:18:14 242

原创 C++深度解析(40)—C++对象模型分析(上)

1.回归本质class是一种特殊的结构体 在内存中class依旧可以看作变量的集合 class与struct遵循相同的内存对齐规则 class中的成员函数与成员变量是分开存放的。即每个对象有独立的成员变量,但所有对象共享类中的成员函数。 编程实验——对象内存布局初探#include<iostream>using namespace std;class ...

2019-07-23 16:37:40 197 1

原创 C++深度解析(39)—多态的概念和意义

1.函数重写回顾父类中被重写的函数依然会继承给子类 子类中重写的函数将覆盖父类中的函数 通过作用域分辨符(::)可以访问到父类中的函数Childc;Parent*p=&c;c.Parent::print();// 从父类中继承c.print()// 在子类中重写,如果不能使用多态,那么重写无意义。p->print();...

2019-07-23 15:05:37 195

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除