c/c++
主要为学习笔记,学习过程中出现的各个知识点
lllle00
这个作者很懒,什么都没留下…
展开
-
与C 区别
文章目录0x01 两者联系0x02 具体区别0x01 两者联系 C 可以说是 C++ 的一个子集,C++ 是 C 的一个增强。0x02 具体区别C++ 为强类型语言在 c 中允许隐式转换,c++ 要求必须使用显示转换C++ 为面向对象语言 (封装,继承,多态)拥有了泛型编程的机制(Template)增加异常处理。增加了运算符与函数的重载增加了标准模板库(STL)增加了引用概念,使得引用函数参数带来子很大方便变量的声明更灵活。C语言要求在函数体开头声明变量,再是执行语句原创 2021-06-11 15:43:27 · 173 阅读 · 0 评论 -
与 C 区别(c++)
文章目录0x01 两者联系0x02 具体区别0x01 两者联系 C 可以说是 C++ 的一个子集,C++ 是 C 的一个增强。0x02 具体区别C++ 为强类型语言在 c 中允许隐式转换,c++ 要求必须使用显示转换C++ 为面向对象语言 (封装,继承,多态)拥有了泛型编程的机制(Template)增加异常处理。增加了运算符与函数的重载增加了标准模板库(STL)增加了引用概念,使得引用函数参数带来子很大方便变量的声明更灵活。C语言要求在函数体开头声明变量,再是执行语句原创 2021-06-10 15:26:48 · 115 阅读 · 0 评论 -
联合体(结构体)
0x01 联合体 多个不同的变量共同使用一段内存的结构称为联合体。可以理解为多个变量的起始地址一样,但包含的内存范围不一样。我们可以使用 union 关键字声明。//实际上常用的声明方法和结构体类似typedef union _fun{ char a[15]; int i;}fun,*pfun;fun a; 其大小为联合体内最大的字节数(如上面的15字节),同时也要是最大字节类型变量的整数倍(所以占用空间为16字节)。...原创 2021-06-08 09:08:56 · 417 阅读 · 0 评论 -
枚举类型(c)
0x01 枚举类型 当一个变量的值的范围是确定的,我们就可以自定义一种变量类型,这种自定义的变量我们称为枚举变量,大小为 4 个字节(x86、x64 一样)。定义方法如下:typedef enum _枚举名{ //以下数据即为枚举类型的值范围 //默认第一个标识为 0 ,后续依次递增,允许自定义标识 pass;}name,*pname;//假设以星期为一个枚举类型typedef enum _day{ Monday,Tuesday,Wednesday,Thurs原创 2021-06-08 09:08:24 · 108 阅读 · 0 评论 -
对齐规则(结构体)
0x01 结构体对齐规则 结构体常规的对齐规则为:基本类型的变量,要求其对齐地址为类型字节大小的整数倍;结构体类型的变量要求为结构体内最大字节变量的字节大小的整数倍结构体的整体大小为结构体内最大字节的整数倍 对于对齐规则我们也可以自定义,使用#pragma pack(n) 即可按 n 字节地址倍数对齐(字节数小于 n 的变量按自身对齐规则对齐)。...原创 2021-06-08 09:07:13 · 215 阅读 · 0 评论 -
拷贝(结构体)
0x01 拷贝 结构体的拷贝可以分为:浅拷贝、深拷贝、写时拷贝。 浅拷贝是指将内容直接赋给另一个,当结构体中出现了指针时,指针的拷贝是将原指针指向的地址赋予新指针,一旦通过原指针对地址进行其它操作,可能会使得新指针出现问题。(如通过原指针 free 内存,新指针变成野指针)C++ 和 C 的编译器默认使用浅拷贝,深拷贝需要程序员自己实现。 深拷贝是将内容拷贝过去,如同复制粘贴过去,包括指针也是拷贝内容过去。 写时拷贝,利用了引用计数,当我们 free 一个指针的内存时,只需要将原创 2021-06-08 09:03:43 · 1498 阅读 · 0 评论 -
声明与使用(结构体)
文章目录0x01 结构体0x02 运算符0x01 结构体 结构体中的数据类型有两种:内建类型、构造类型。内建类型就是如同字符、数组一类直接支持的,而构建类型就是如同结构体一样的。 结构体本身也是由内建类型的数据或者其它构建类型的数据组成。常用的声明方法如下typedef struct _strudent{ int id; int age; char name[20];}student,*pstudent; //调用 pstudent 等效于 struct _s原创 2021-06-08 09:07:48 · 215 阅读 · 0 评论 -
声明与类型(指针)
文章目录0x01 介绍0x02 初始化0x03 void *0x04 复杂声明0x01 介绍 指针本身也是一个变量,其与其它普通变量的不同在于,它的值是一个内存地址,且明确了该内存的宽度(这个由指针的类型确定)。 若我们用另一个指针存储了这个指针的地址,那么这个 “另一个指针” 被称为二级指针。0x02 初始化 以下两种方法的初始化等效。// 方法一int a =1;int *p = &a;// 方法二int a=1;int *p;p = &a;0x0原创 2021-06-08 09:09:23 · 287 阅读 · 0 评论 -
声明(字符串)
文章目录0x01 引号0x02 多字节字符串0x03 声明0x01 引号 对于双引号,表示字符串,结尾自带一个不可见字符\0,存储于静态区,如:"a" 表示有两个字符,其中结尾处有一个不可见的字符 \0 。 对于单引号,表示字符常量,不存储于静态区,不占内存,赋值给谁后,就存储在哪里,只表示一个字符。0x02 多字节字符串 对于一个多字节字符串,如果没有特别规定则默认英文字符占一个字节,中文占两个字节;对于宽字符串,每个字母占的字节都是一样,均为两个字节。char str1[] ="原创 2021-06-07 13:22:11 · 963 阅读 · 0 评论 -
修改(字符串)
0x01 操作与库函数 对于字符串的操作函数按字符串类型可以分为两类:多字节字符串、宽字节字符串。多字节字符串:在原本的 ASCLL 字符集上发展而来,英文字符一个字节,中文两个字节宽字节字符串:Unicode 字符集,所有字符均为宽字节,如:UTF-16、 程序为这两种字符串提供三套 API ,对于多字节类型字符串,可以使用 strxxx 的函数;对于宽字节类型字符串,可以使用 wcsxxx 的函数。 还有一种 API 根据项目预先设定的字符串类型,自动转换为相对应的函数,函数一原创 2021-06-07 13:21:25 · 122 阅读 · 0 评论 -
多级指针(指针)
0x01 二级指针 指向变量的指针可以称为一级指针,而指向一级指针的指针可以称为二级指针。二级指针存放的内容就是一级指针的地址。应用: 当我们将指针地址作为实参传入函数中,函数中的形参必须使用二级指针。指针地址作为实参传入,故我们需要使用二级指针接受一级指针的地址,进行一次解引用后,就可以修改一级指针指向的地址。0x02 指针传参 函数中,指针传参会有很多中可能出现,但我个人感觉对于多种情况都可以用一种等效的方法理解,方法如下://假设存在一个函数int fun(int *p原创 2021-06-07 09:31:02 · 152 阅读 · 0 评论 -
引用与解引用(指针)
0x01 解引用 这是对指针的一种应用。解引用是指:通过指针,找到对应的内存和内存中的数据。我们可以通过解引用访问或修改指针指向的内存内容。 解引用后等价于指针指向的变量。int a =1;int *p = &a;//下面两者是等价的*p += 1;a += 1; 0x02 引用与解引用 & 与 * 互为逆运算。& ,其作用是取变量的地址;* ,其作用是取地址对应的内存,内存长度由指针类型确定,void 类型表示不确定,GCC 默认一个字节。int原创 2021-06-07 08:51:44 · 14484 阅读 · 0 评论 -
内联函数(函数)
文章目录0x01 inline 关键字0x02 static 关键字0x01 inline 关键字 对于加了 inline 关键字的函数,我们常称为内联函数,在调用这个函数时,这个函数会像宏定义一样直接展开,不再像普通函数一样进行入栈出栈、传参等操作。其与宏的不同在于,宏不支持调试,但内联函数支持调试;inline 关键字的内联只是对编译器的一个建议,当编译器认为函数不复杂时,才会真正内联,所以决定权在于编译器,并非 inline 关键字。0x02 static 关键字 限定了函数只原创 2021-06-07 08:36:38 · 120 阅读 · 0 评论 -
调用约定(函数)
0x01 调用约定 调用约定规定了调用者和被调用者之间的栈上参数传递和清理。常见的有三种:cdecl、stdcall、fastcall。 在 x86 系统中的调用约定有:Cdecl:C 语言默认的调用约定参数从右往左依次入栈调用者栈平衡Stdcall需要声明参数从右往左依次入栈被调用者栈平衡Fastcall前两个参数放入ecx,edx,后面参数从右往左依次入栈被调用者栈平衡 在 x64 系统中的调用约定只有 fastcall,其它调用约定均被舍原创 2021-06-07 08:27:35 · 131 阅读 · 0 评论 -
传参(数组)
文章目录0x01 首地址0x02 参数0x01 首地址 对于首地址,其指向数组地址的开头,而其中 a 与 &a 所表达的意思是不一样的。int a[10] = {0};/** a:值为数组的首地址,类型为 int ** &a:值为数组的首地址,类型为 int (*a)[10]* 两者的值一样,均为数组的首地址* 两者的类型不一样,所以 a 所表示的有效范围为 sizeof(int)* &a 所表示的有效范围为 sizeof(int)*10* 类型的不一使得 +原创 2021-06-06 23:46:03 · 441 阅读 · 0 评论 -
函数的调用
0x01 函数调用 当我们调用其它函数库时需要包含其库文件。 如调用随机函数需要包含头文件 stdlib.h 。在使用 rand() 随机函数时,我们需要使用 srand((unsigned int)time(0)) 生成一个随机数种子,不然每次调用时获得的随机数并不随机。time(0):返回当前时间,类型为 time_t(实际上时长整型)unsigned int :srand () 输入应为 unsigned int 类型,所以我们使用了强制转换。...原创 2021-06-06 23:40:57 · 72 阅读 · 0 评论 -
优先级(运算符)
0x01 运算符优先级 口诀:括箭点,单算移比较,位辑三等逗 解释:括号、箭头号、点号、单目运算符、算数运算符、移位运算符、比较运算符、位运算符、逻辑运算符、三目运算符、赋值运算符、逗号...原创 2021-06-06 23:35:57 · 88 阅读 · 0 评论 -
自增符(运算符)
文章目录0x01 自增符0x01 自增符 对于 i++ 和 ++i ,其作用相似,执行顺序不一,前者先引用 i 再进行自增,后者相反。 在 C++ 中,i 是一个对象,使用 ++i 的效率高于 i++,但当其作为一个单独一行的语句时,两者效率时一样的。因为 ++i 返回一个引用,就是修改后的 i ,而 i++返回一个拷贝,拷贝的消耗大于引用。...原创 2021-06-06 23:33:14 · 264 阅读 · 0 评论 -
函数与指针
文章目录0x01 函数指针0x02 指针函数0x03 函数名与 &0x01 函数指针 函数名即为函数地址,当指针中存放了函数地址,即为函数指针。 函数指针的定义有两种方法:int fun_c(int a){ pass; return 0;} //被指向的函数,fun_c 为该函数的地址/***方法一:**利用 typedef 定义函数指针的类型**然后利用这个函数指针类型定义函数指针*/typrdef int (*F)(int); //定义函原创 2021-06-01 15:54:45 · 58 阅读 · 0 评论 -
常量与指针
文章目录0x01 常量简介0x02 常量指针0x03 指针常量0x01 常量简介 广义上是指不变的量,虽然不完全正确,但很多时候,我们也确实可以这么理解。0x02 常量指针 常量指针可以理解为:一个指针,这个指针是一个常量,指针一旦被赋值就不可以改变。int * const p;/*** p 与 const 结合,再与 * 结合,所以看作常量指针** p 指向某内存地址,该地址不可被修改** 数组头的指针就是一个默认的常量指针*/0x03 指针常量 指针常量可以理解原创 2021-06-01 14:57:18 · 54 阅读 · 0 评论 -
文件操作初认识
文章目录0x01 文件简介0x02 文件系统0x03 文件类型0x04 文件打开0x05 文件读写0x06 读写指针0x01 文件简介 文件可以分为普通文件和设备文件。 普通文件存储在磁盘等外部设备中,需要时读入内存中。 设备文件,将外部设备也看作一个文件来进行管理,对外部设备的输入输出也等同于对文件的读写。0x02 文件系统 文件系统是指操作系统中用于组织和管理磁盘上文件的方法和数据结构,其负责文件的读取,修改,存储等等操作。 Windows 上常见的文件系统有 FAT、原创 2021-05-31 17:19:05 · 86 阅读 · 0 评论 -
条件编译介绍
文章目录0x01 条件编译简介0x01 条件编译简介 在 C 语言的源代码中,可以通过一种方式规定代码是否会被编译进程序中,这种方式叫做条件编译。条件编译格式如下://格式一#ifdef macro_name //程序一,当标识符有定义程序一的代码将会被编译 pass;#else //程序二 pass;#endif//格式二#ifndef macro_name //ifndef 表示若没有定义 //程序一 pass; #else //程序二 pass;原创 2021-05-31 11:31:55 · 623 阅读 · 0 评论 -
宏——初认识
文章目录0x01 宏简介0x02 优缺点0x01 宏简介 宏定义是指用一个标志符代表一个字符串,该标志符就称为宏名。在程序编译预处理阶段,所有宏名将会被替换为宏定义中的字符串,这个操作被称为宏展开 定义格式如下:#define macro_name str //不带参数#define macro_name(argv) str //带参数//宏名一般大写,宏定义结尾处不需要使用分号结尾0x02 优缺点 宏定义有优点也有缺点有自解释性可以减少后期修改无法进行类型检查无原创 2021-05-30 23:28:03 · 125 阅读 · 0 评论 -
内存管理初认识
文章目录0x01 内存简介0x02 堆和栈0x03 内存地址0x04 内存泄漏0x01 内存简介 对于每个程序都有其独立的 4 G 的虚拟内存空间。Windows 在默认的情况下会将高地址的 2GB 空间分配给内核(也可以配置 1GB)。Linux 默认情况下将高地址的 1GB 空间分配给内核。 其中的 32 位系统程序存放布局图示意如下: 对于其中的进程空间,可以进行如下的划分:0x02 堆和栈 堆和栈是两个东西,各有不同栈: 由系统分配与回收内存,从高原创 2021-05-29 13:57:48 · 182 阅读 · 0 评论 -
参数(函数)
文章目录0x01 返回值0x02 传参0x03 调用约定0x04 inline 关键字0x05 static 关键字0x01 返回值 函数的返回值不能时指向栈内存的指针或引用,因为栈内存是函数的局部变量,一旦函数调用结束,返回的该指针指向内存已自动释放,如果对其进行操作,造成的后果无法预测。0x02 传参 函数中形参和实参是两个不同的,形参是实参的一个拷贝。传入参数的类型不同,对实参的影响也会有所不同。传值:形参是实参值的拷贝,修改形参的值无法改变实参的值。传指针:实参是地址,形参拷贝了原创 2021-05-27 13:08:00 · 102 阅读 · 0 评论 -
多维数组(数组)
文章目录0x01 一维数组0x02 二维数组0x03 首地址0x04 参数0x01 一维数组 数组的长度定义不可以使用变量 若需要求数组长度可以使用 sizeof(),方法如下:int a[]= {0,1,5,4,9,4,32,8,4,4,65,4,5};int leng = 0;leng = sizeof(a)/sizeof(a[0]); /**sizeof(a) 可以求出总体数组所占空间*sizeof(a[0]) 可以求出移一位数组所占的空间从而求出整体*/ 字符串原创 2021-05-25 15:21:29 · 197 阅读 · 0 评论 -
程序转向语句
文章目录0x01 函数调用0x02 转向语句一、 goto 语句二、循环中的转向三、return 语句0x01 函数调用 当我们调用其它函数库时需要包含其库文件。 如调用随机函数需要包含头文件 stdlib.h 。在使用 rand() 随机函数时,我们需要使用 srand((unsigned int)time(0)) 生成一个随机数种子,不然每次调用时获得的随机数并不随机。time(0):返回当前时间,类型为 time_t(实际上时长整型)unsigned int :srand ()原创 2021-05-24 15:23:06 · 231 阅读 · 0 评论 -
判定顺序(运算符)
文章目录0x01 自增符0x02 贪心算法0x01 自增符 对于 i++ 和 ++i ,其作用相似,执行顺序不一,前者先引用 i 再进行自增,后者相反。 在 C++ 中,i 是一个对象,使用 ++i 的效率高于 i++,当其作为一个单独一行的语句时,两者效率时一样的。因为 ++i 返回一个引用,而 i++返回一个拷贝,拷贝的消耗大于引用。0x02 贪心算法 对于如同 a+++b 的语句,编译器采用贪心算法,即从左到右尽量形成一个语句,所以会被分析成 (a++)+b 。...原创 2021-05-24 14:29:03 · 110 阅读 · 0 评论 -
I / O (printf/scanf)
文章目录0x01 输入输出0x02 std 流0x03 安全0x01 输入输出 我们常用的输入函数:scanf、getchar、getch。 scanf 函数常见,不多解释。使用 getch 函数,输入时,输入内容不显示在屏幕上,也不用回车键。getchar 函数类似于 scanf 函数,但一次函数调用获得一个字符。使用 scanf 函数可能会出现 c4996 警告,这是指调用了一个不安全的函数或变量,而 scanf 函数没有对输入进行溢出检测,可能会出现缓存区溢出漏洞。 我们在获得原创 2021-05-23 08:22:23 · 73 阅读 · 0 评论 -
变量存储
文章目录0x01 内存空间0x02 变量0x03 参考0x01 内存空间 对于每个程序都有其独立的 4 G 的虚拟内存空间。Windows 在默认的情况下会将高地址的 2GB 空间分配给内核(也可以配置 1GB)。Linux 默认情况下将高地址的 1GB 空间分配给内核。 其中的 32 位系统程序存放布局图示意如下:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ywKG4xm9-1621665597407)(https://i.loli.net/202原创 2021-05-22 14:40:14 · 124 阅读 · 0 评论 -
类型转换(数据类型)
文章目录0x01 内建类型0x02 类型的范围0x03 类型转换0x01 内建类型 c 语言中的数据必须明确数据的类型,而 c++ 还有类型的安全检测,所有的数据都可以从基本的数据类型中找到原型。 c 的内建类型有:字符类型、整型、浮点数(单双)、布尔型、有无符号(前缀,默认有符号)字符类型: char(ASCLL类型,一个字节)、wchar_t(UNICODE类型,2字节, Linux 中 4 字节)(赋值时在字符前加 “ L ” ) 对于 Unicode 编码常采用 2 或原创 2021-05-20 00:05:52 · 126 阅读 · 0 评论 -
浮点数存储
文章目录0x01 浮点数的存储0x02 小数部分求法0x03 阶码范围0x04 参考0x01 浮点数的存储 c/c++ 都按照浮点数表示法来表示浮点数,使用二进制的科学技术法。二进制的科学计数法: 11011.1101 = 1.10111101 * 2^4上面的这个数 1.10111101 为尾数,4 为指数,0 为符号位(若是负数则为 1 ) 所以浮点数的存储是将连续的多个字节(单精度为 4 ,双则为 8 )分为三个部分来表示二进制科学计数法。存储顺序:符号位(低地址)、阶码位原创 2021-05-19 09:59:38 · 408 阅读 · 0 评论 -
程序开始处执行的函数
程序最早执行的函数时什么函数: 最早执行的函数是 mainCRTStartup 。 在 CONSOLE(无 windows 界面)程序中,main 函数是用户定义的执行入口点,当程序编译成功之后,连接器(linker)会将 mainCRTStartup 连接到 exe 中,所以 exe 执行时,一开始执行的就是 mainCRTStartup,而不是main。 这是因为程序在执行时会调用备种各样的运行时库函数,因此程序执行之前必须要先初始化好运行时库,mainCRTStartup 函数会负责原创 2021-05-17 22:59:06 · 614 阅读 · 0 评论 -
变量的生存周期 (C语言)
变量的分类 对于变量的分类从不同的角度有不同的结果从变量的作用域来看:局部变量全局变量从变量的存储方式来看静态存储方式动态存储方式全局变量 显而易见,作用域是全局的,其作用域为从定义的位置到整个源文件结尾,通常来说,在函数外部声明变量即为全局变量。 如果我们想在函数内部声明一个全局变量,需要时用关键字 global 即可。 对于全局变量又可以进一步的区分: 静态外部全局变量: 由于可能在某一个源文件中将全局变量的定义放在了需要使用该全局变量的函数原创 2020-09-23 23:05:33 · 1347 阅读 · 0 评论