
c/c++
Comma_dev
这个作者很懒,什么都没留下…
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
C++学习笔记【0】—— 有用的网站
cplusplushttp://www.cplusplus.com/cpp referencehttps://en.cppreference.com/w/技术论坛https://stackoverflow.com/学习网站https://www.geeksforgeeks.org/比较全面的C++博客https://r00tk1ts.github.io/https://www.cnblogs.com/haippy...原创 2020-09-07 16:35:08 · 123 阅读 · 0 评论 -
C++学习笔记【四十二】—— STL 教程_Vector
C++ STL(标准模板库)是一套功能强大的 C++ 模板类,提供了通用的模板类和函数,这些模板类和函数可以实现多种流行和常用的算法和数据结构,如向量、链表、队列、栈。使用向量#include <iostream>#include <vector>using namespace std;int main(){ // 创建一个向量存储 int vector<int> vec; int i; // 显示 vec 的原始大小 cout转载 2020-08-26 15:33:29 · 116 阅读 · 0 评论 -
C++学习笔记【四十一】—— Web 编程
文章目录CGIWeb 浏览编程示例:CGI公共网关接口(CGI),是一套标准,定义了信息是如何在 Web 服务器和客户端脚本之间进行交换的。CGI 规范目前是由 NCSA 维护的,NCSA 定义 CGI 如下:公共网关接口(CGI),是一种用于外部网关程序与信息服务器(如 HTTP 服务器)对接的接口标准。目前的版本是 CGI/1.1,CGI/1.2 版本正在推进中。架构如下:Web 浏览为了更好地了解 CGI 的概念,让我们点击一个超链接,浏览一个特定的网页或 URL,看看会发生什么转载 2020-08-26 15:22:42 · 125 阅读 · 0 评论 -
C++学习笔记【四十】—— 多线程
多线程是多任务处理的一种特殊形式,多任务处理允许让电脑同时运行两个或两个以上的程序。一般情况下,两种类型的多任务处理:基于进程和基于线程。基于进程的多任务处理是程序的并发执行。基于线程的多任务处理是同一程序的片段的并发执行。多线程程序包含可以同时运行的两个或多个部分。这样的程序中的每个部分称为一个线程,每个线程定义了一个单独的执行路径。本教程假设您使用的是 Linux 操作系统,我们要使用 POSIX 编写多线程 C++ 程序。POSIX Threads 或 Pthreads 提供的 API 可转载 2020-08-26 14:37:33 · 125 阅读 · 0 评论 -
C++学习笔记【三十九】—— 信号处理
信号是由操作系统传给进程的中断,会提早终止一个程序。在 UNIX、LINUX、Mac OS X 或 Windows 系统上,可以通过按 Ctrl+C 产生中断。有些信号不能被程序捕获,但是下表所列信号可以在程序中捕获,并可以基于信号采取适当的动作。这些信号是定义在 C++ 头文件 < csignal > 中。signal() 函数signal(registered signal, signal handler)这个函数接收两个参数:第一个参数是一个整数,代表了信号的编号;第二个参数是一转载 2020-08-26 13:53:11 · 152 阅读 · 0 评论 -
C++学习笔记【三十八】—— 预处理器
预处理器是一些指令,指示编译器在实际编译之前所需完成的预处理。所有的预处理器指令都是以井号(#)开头,只有空格字符可以出现在预处理指令之前。预处理指令不是 C++ 语句,所以它们不会以分号(;)结尾。C++ 还支持很多预处理指令,比如 #include、#define、#if、#else、#line 等,让我们一起看看这些重要指令。#define 预处理#define PI 3.14159#define MIN(a,b) (a<b ? a : b)#ifdef NULL #def转载 2020-08-26 13:41:54 · 233 阅读 · 0 评论 -
C++学习笔记【三十七】—— 模板
模板是泛型编程的基础,泛型编程即以一种独立于任何特定类型的方式编写代码。模板是创建泛型类或函数的蓝图或公式。库容器,比如迭代器和算法,都是泛型编程的例子,它们都使用了模板的概念。每个容器都有一个单一的定义,比如 向量,我们可以定义许多不同类型的向量,比如 vector 或 vector 。您可以使用模板来定义函数和类,接下来让我们一起来看看如何使用。函数模板一般形式:template <typename/class type> ret-type func-name(param.转载 2020-08-26 13:25:55 · 124 阅读 · 0 评论 -
C++学习笔记【三十六】—— 命名空间
文章目录命名空间的定义及使用using 指令不连续的命名空间定义嵌套的命名空间在 C++ 应用程序中。例如,您可能会写一个名为 xyz() 的函数,在另一个可用的库中也存在一个相同的函数 xyz()。这样,编译器就无法判断您所使用的是哪一个 xyz() 函数。因此,引入了命名空间这个概念,专门用于解决上面的问题,它可作为附加信息来区分不同库中相同名称的函数、类、变量等。使用了命名空间即定义了上下文。本质上,命名空间就是定义了一个范围。命名空间的定义及使用namespace namespace_nam转载 2020-08-26 09:12:16 · 170 阅读 · 0 评论 -
C++学习笔记【三十五】—— 动态内存
C++ 程序中的内存分为两个部分:栈:在函数内部声明的所有变量都将占用栈内存。堆:这是程序中未使用的内存,在程序运行时可用于动态分配内存。您无法提前预知需要多少内存来存储某个定义变量中的特定信息,所需内存的大小需要在运行时才能确定。在 C++ 中,您可以使用特殊的运算符为给定类型的变量在运行时分配堆内的内存,这会返回所分配的空间地址。这种运算符即 new 运算符。如果您不再需要动态分配的内存空间,可以使用 delete 运算符,删除之前由 new 运算符分配的内存。变量内存动态分配单一变量转载 2020-08-25 16:52:48 · 124 阅读 · 0 评论 -
C++学习笔记【三十四】—— 异常处理
C++ 异常处理涉及到三个关键字:try、catch、throw。throw: 当问题出现时,程序会抛出一个异常。这是通过使用 throw 关键字来完成的。catch: 在您想要处理问题的地方,通过异常处理程序捕获异常。catch 关键字用于捕获异常。try: try 块中的代码标识将被激活的特定异常。它后面通常跟着一个或多个 catch 块。如果有一个块抛出一个异常,捕获异常的方法会使用 try 和 catch 关键字。try 块中放置可能抛出异常的代码,try 块中的代码被称为保护代码。使用转载 2020-08-25 15:23:02 · 185 阅读 · 0 评论 -
C++学习笔记【三十三】—— 文件和流
文章目录打开&关闭文件读取&写入文件文件位置指针我们已经使用了 iostream 标准库,它提供了 cin 和 cout 方法分别用于从标准输入读取流和向标准输出写入流。从文件读取流和向文件写入流。这就需要用到 C++ 中另一个标准库 fstream,它定义了三个新的数据类型打开&关闭文件如果您想要以写入模式打开文件,并希望截断文件,以防文件已存在,那么您可以使用下面的语法:ofstream outfile;outfile.open("file.dat", ios::o转载 2020-08-25 14:34:53 · 128 阅读 · 0 评论 -
C++学习笔记【三十二】—— 接口(抽象类)
接口描述了类的行为和功能,而不需要完成类的特定实现。C++ 接口是使用抽象类来实现的,抽象类与数据抽象互不混淆,数据抽象是一个把实现细节与相关的数据分离开的概念。如果类中至少有一个函数被声明为纯虚函数,则这个类就是抽象类。纯虚函数是通过在声明中使用 “= 0” 来指定的。class Box{ public: // 纯虚函数 virtual double getVolume() = 0; private: double length; //转载 2020-08-24 15:24:53 · 113 阅读 · 0 评论 -
C++学习笔记【三十一】—— 数据封装
封装是面向对象编程中的把数据和操作数据的函数绑定在一起的一个概念,这样能避免受到外界的干扰和误用,从而确保了安全。数据封装引申出了另一个重要的 OOP 概念,即数据隐藏。数据封装是一种把数据和操作数据的函数捆绑在一起的机制,数据抽象是一种仅向用户暴露接口而把具体的实现细节隐藏起来的机制。C++ 通过创建类来支持封装和数据隐藏(public、protected、private)。我们已经知道,类包含私有成员(private)、保护成员(protected)和公有成员(public)成员。默认情况下,在类中转载 2020-08-24 14:59:40 · 136 阅读 · 0 评论 -
C++学习笔记【三十】—— 数据抽象
就 C++ 编程而言,C++ 类为数据抽象提供了可能。它们向外界提供了大量用于操作对象数据的公共方法,也就是说,外界实际上并不清楚类的内部实现。例如,您的程序可以调用 sort() 函数,而不需要知道函数中排序数据所用到的算法。实际上,函数排序的底层实现会因库的版本不同而有所差异,只要接口不变,函数调用就可以照常工作。在 C++ 中,我们使用类来定义我们自己的抽象数据类型(ADT)。访问标签强制抽象在 C++ 中,我们使用访问标签来定义类的抽象接口。一个类可以包含零个或多个访问标签:使用公共标签定转载 2020-08-24 14:55:16 · 130 阅读 · 0 评论 -
C++学习笔记【二十九】—— 多态 虚函数
多态按字面的意思就是多种形态。当类之间存在层次结构,并且类之间是通过继承关联时,就会用到多态。C++ 多态意味着调用成员函数时,会根据调用函数的对象的类型来执行不同的函数。C++中的虚函数的作用主要是实现了多态的机制。关于多态,简而言之就是用父类型别的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数。这种技术可以让父类的指针有“多种形态”,这是一种泛型技术。所谓泛型技术,说白了就是试图使用不变的代码来实现可变的算法。比如:模板技术,RTTI技术,虚函数技术,要么是试图做到在编译时决议,要么转载 2020-08-24 14:46:29 · 159 阅读 · 0 评论 -
C++学习笔记【二十八】—— 重载运算符和重载函数&函数重写&函数隐藏
C++ 允许在同一作用域中的某个函数和运算符指定多个定义,分别称为函数重载和运算符重载。重载声明是指一个与之前已经在该作用域内声明过的函数或方法具有相同名称的声明,但是它们的参数列表和定义(实现)不相同。当您调用一个重载函数或重载运算符时,编译器通过把您所使用的参数类型与定义中的参数类型进行比较,决定选用最合适的定义。选择最合适的重载函数或重载运算符的过程,称为重载决策。C++ 中的函数重载在同一个作用域内,可以声明几个功能类似的同名函数,但是这些同名函数的形式参数(指参数的个数、类型或者顺序)必须转载 2020-08-24 14:17:10 · 265 阅读 · 0 评论 -
C++学习笔记【二十七】——C++继承
面向对象程序设计中最重要的一个概念是继承。继承允许我们依据另一个类来定义一个类,这使得创建和维护一个应用程序变得更容易。这样做,也达到了重用代码功能和提高执行效率的效果。当创建一个类时,您不需要重新编写新的数据成员和成员函数,只需指定新建的类继承了一个已有的类的成员即可。这个已有的类称为基类,新建的类称为派生类。基类 & 派生类一个类可以派生自多个类,这意味着,它可以从多个基类继承数据和函数。定义一个派生类,我们使用一个类派生列表来指定基类。类派生列表以一个或多个基类命名,形式如下:clas转载 2020-08-24 10:13:08 · 534 阅读 · 0 评论 -
C++学习笔记【二十六】——类的静态成员
静态成员数据说明可见另一篇文章:C++学习笔记【六】—— 存储类- 静态成员变量属于整个类所有- 静态成员变量的生命期不依赖于任何对象,为程序的生命周期- 可以通过类名直接访问公有静态成员变量- 所有对象共享类的静态成员变量- 可以通过对象名访问公有静态成员变量- 静态成员变量需要在类外单独分配空间- 静态成员变量在程序内部位于全局数据区 (Type className::VarName = value)静态成员函数如果把函数成员声明为静态的,就可以把函数与类的任何特定对象转载 2020-08-19 10:56:59 · 129 阅读 · 0 评论 -
C++学习笔记【二十五】——指向类的指针
一个指向 C++ 类的指针与指向结构的指针类似,访问指向类的指针的成员,需要使用成员访问运算符 ->,就像访问指向结构的指针一样。与所有的指针一样,您必须在使用指针之前,对指针进行初始化。#include <iostream>using namespace std;class Box{ public: // 构造函数定义 Box(double l=2.0, double b=2.0, double h=2.0) { cou转载 2020-08-19 09:09:52 · 138 阅读 · 0 评论 -
C++学习笔记【二十四】——this指针
在 C++ 中,每一个对象都能通过 this 指针来访问自己的地址。this 指针是所有成员函数的隐含参数。因此,在成员函数内部,它可以用来指向调用对象。友元函数没有 this 指针,因为友元不是类的成员。只有成员函数才有 this 指针。#include <iostream>using namespace std;class Box{ public: // 构造函数定义 Box(double l=2.0, double b=2.0, double h=2转载 2020-08-19 09:06:44 · 122 阅读 · 0 评论 -
C++学习笔记【二十三】——内联函数
内联函数的说明C++ 内联函数是通常与类一起使用。如果一个函数是内联的,那么在编译时,编译器会把该函数的代码副本放置在每个调用该函数的地方。对内联函数进行任何修改,都需要重新编译函数的所有客户端,因为编译器需要重新更换一次所有的代码,否则将会继续使用旧的函数。如果想把一个函数定义为内联函数,则需要在函数名前面放置关键字 inline,在调用函数之前需要对函数进行定义。如果已定义的函数多于一行,编译器会忽略 inline 限定符。在类定义中的定义的函数都是内联函数,即使没有使用 inline 说明转载 2020-08-19 08:49:40 · 180 阅读 · 0 评论 -
C++学习笔记【二十二】——友元函数
类的友元函数是定义在类外部,但有权访问类的所有私有(private)成员和保护(protected)成员。尽管友元函数的原型有在类的定义中出现过,但是类中只是声明函数,友元函数并不是成员函数。友元可以是一个函数,该函数被称为友元函数;友元也可以是一个类,该类被称为友元类,在这种情况下,整个类及其所有成员都是友元。如果要声明函数为一个类的友元,需要在类定义中该函数原型前使用关键字 friend。友元函数#include <iostream>using namespace std;cla转载 2020-08-18 16:29:02 · 123 阅读 · 0 评论 -
C++学习笔记【二十一】—— 拷贝构造函数
定义拷贝构造函数是一种特殊的构造函数,它在创建对象时,是使用同一类中之前创建的对象来初始化新创建的对象。拷贝构造函数通常用于:通过使用另一个同类型的对象来初始化新创建的对象。复制对象把它作为参数传递给函数。复制对象,并从函数返回这个对象。如果在类中没有定义拷贝构造函数,编译器会自行定义一个。如果类带有指针变量,并有动态内存分配,则它必须有一个拷贝构造函数。拷贝构造函数的最常见形式如下://在这里,obj 是一个对象引用,该对象是用于初始化另一个对象的。classname (const c转载 2020-08-18 09:53:23 · 298 阅读 · 0 评论 -
C++学习笔记【二十】—— 类构造函数 & 析构函数
类的构造函数类的构造函数是类的一种特殊的成员函数,它会在每次创建类的新对象时执行。构造函数的名称与类的名称是完全相同的,并且不会返回任何类型,也不会返回 void。构造函数可用于为某些成员变量设置初始值。不带参数的构造函数#include <iostream>using namespace std;class Line{ public: void setLength( double len ); double getLength( void );转载 2020-08-17 11:12:50 · 215 阅读 · 1 评论 -
C++学习笔记【十九】—— 类访问修饰符public&private&protected
数据封装是面向对象编程的一个重要特点,它防止函数直接访问类类型的内部成员。一个类可以有多个 public、protected 或 private 标记区域。每个标记区域在下一个标记区域开始之前或者在遇到类主体结束右括号之前都是有效的。成员和类的默认访问修饰符是 private。公有(public)成员公有成员在程序中类的外部是可访问的。您可以不使用任何成员函数来设置和获取公有变量的值,可以直接通过对象来设置或读取公有变量的值。私有(private)成员私有成员变量或函数在类的外部是不可访问的,甚至转载 2020-08-14 14:40:56 · 699 阅读 · 0 评论 -
C++学习笔记【十八】—— 类成员函数public
类的成员函数是指那些把定义和原型写在类定义内部的函数,就像类定义中的其他变量一样。类成员函数有两种定义方法:将函数定义在类的内部将函数定义在类的外部,单独使用范围解析运算符 :: 来定义将函数定义在类的内部在类定义中定义的成员函数是把函数声明为内联的,即便没有使用 inline 标识符。例程如下:class Box{ public: double length; // 长度 double breadth; // 宽度 doubl转载 2020-08-14 10:24:48 · 9453 阅读 · 0 评论 -
C++学习笔记【十七】—— 类&对象简介
C++ 在 C 语言的基础上增加了面向对象编程,类是 C++ 的核心特性,通常被称为用户定义的类型。类用于指定对象的形式,它包含了数据表示法和用于处理数据的方法。类中的数据和方法称为类的成员。函数在一个类中被称为类的成员。类的定义定义一个类,本质上是定义一个数据类型的蓝图。这实际上并没有定义任何数据,但它定义了类的名称意味着什么,也就是说,它定义了类的对象包括了什么,以及可以在这个对象上执行哪些操作。类定义是以关键字 class 开头,后跟类的名称。类的主体是包含在一对花括号中。类定义后必须跟着一个转载 2020-08-14 09:52:38 · 169 阅读 · 0 评论 -
C++学习笔记【十六】—— 数据结构struct
定义struct type_name {member_type1 member_name1;member_type2 member_name2;member_type3 member_name3;..} object_names;在结构定义的末尾,最后一个分号之前,您可以指定一个或多个结构变量,这是可选的。下面是声明一个结构体类型 Books,变量为 book:struct Books{ char title[50]; char author[50]; char转载 2020-08-12 20:19:44 · 463 阅读 · 0 评论 -
C++学习笔记【十五】—— 基本的输入输出
I/O 库头文件转载 2020-08-12 20:00:44 · 97 阅读 · 0 评论 -
C++学习笔记【十四】—— 日期 & 时间
C++ 标准库没有提供所谓的日期类型。C++ 继承了 C 语言用于日期和时间操作的结构和函数。为了使用日期和时间相关的函数和结构,需要在 C++ 程序中引用 头文件。中四个与时间相关的类型有四个与时间相关的类型:clock_t、time_t、size_t 和 tm。类型 clock_t、size_t 和 time_t 能够把系统时间和日期表示为某种整数。结构类型 tm 把日期和时间以 C 结构的形式保存,tm 结构的定义如下:struct tm { int tm_sec; // 秒,正常范转载 2020-08-12 09:29:23 · 218 阅读 · 1 评论 -
C++学习笔记【十三】——引用
引用变量是一个别名,也就是说,它是某个已存在变量的另一个名字。一旦把引用初始化为某个变量,就可以使用该引用名称或变量名称来指向变量。引用与指针的区别不存在空引用。引用必须连接到一块合法的内存。一旦引用被初始化为一个对象,就不能被指向到另一个对象。指针可以在任何时候指向到另一个对象。引用必须在创建时被初始化。指针可以在任何时间被初始化。创建引用int i = 17;double d;int& r=i;double& s=d;在这些声明中,& 读作引用。因此,第一转载 2020-08-12 09:06:24 · 246 阅读 · 0 评论 -
C++学习笔记【十二】—— 指针
指针是一个变量,其值为另一个变量的地址,即,内存位置的直接地址。定义指针int *a;使用指针:int b= 1;int *a;a= &b;b= *a+1;Null 指针在变量声明的时候,如果没有确切的地址可以赋值,为指针变量赋一个 NULL 值是一个良好的编程习惯。赋为 NULL 值的指针被称为空指针。NULL 指针是一个定义在标准库中的值为零的常量。在大多数的操作系统上,程序不允许访问地址为 0 的内存,因为该内存是操作系统保留的。然而,内存地址 0 有特别重要的意义,它表明该原创 2020-08-10 11:14:40 · 167 阅读 · 0 评论 -
C++学习笔记【十一】—— 字符串
C++ 提供了以下两种类型的字符串表示形式:C 风格字符串C++ 引入的 string 类类型C 风格字符串字符串实际上是使用 null 字符 ‘\0’ 终止的一维字符数组。char greeting[6] = {'H', 'e', 'l', 'l', 'o', '\0'};char greeting[] = "Hello";C++ 中有大量的函数用来操作以 null 结尾的字符串:C++ 引入的 string 类类型#include <string>int原创 2020-08-10 10:49:53 · 164 阅读 · 0 评论 -
C++学习笔记【十】—— 数组
C++数组存储一个固定大小的相同类型元素的顺序集合。声明数组在 C++ 中要声明一个数组,需要指定元素的类型和元素的数量:type arrayName [ arraySize ];初始化数组1.double balance[5] = {1000.0, 2.0, 3.4, 7.0, 50.0};2.double balance[] = {1000.0, 2.0, 3.4, 7.0, 50.0};3.balance[4] = 50.0;多维数组N维数组声明的一般形式:type name[siz原创 2020-08-10 10:39:15 · 159 阅读 · 0 评论 -
C++学习笔记【九】—— 数学运算&随机数
数学运算C++ 内置了丰富的数学函数,可对各种数字进行运算。为了利用这些函数,您需要引用数学头文件 。随机数在许多情况下,需要生成随机数。关于随机数生成器,有两个相关的函数。一个是 rand(),该函数只返回一个伪随机数。生成随机数之前必须先调用 srand() 函数。实例中使用了 time() 函数来获取系统时间的秒数,通过调用 rand() 函数来生成随机数。#include <iostream>#include <ctime>#include <cstd原创 2020-08-10 10:07:41 · 168 阅读 · 0 评论 -
C++学习笔记【八】—— 函数参数&匿名函数Lambda
传值调用C++ 使用传值调用方法来传递参数。一般来说,这意味着函数内的代码不会改变用于调用函数的实际参数。指针调用向函数传递参数的指针调用方法,把参数的地址复制给形式参数。在函数内,该地址用于访问调用中要用到的实际参数。这意味着,修改形式参数会影响实际参数。引用调用向函数传递参数的引用调用方法,把引用的地址复制给形式参数。在函数内,该引用用于访问调用中要用到的实际参数。这意味着,修改形式参数会影响实际参数。匿名函数LambdaC++11 提供了对匿名函数的支持,称为 Lambda ..原创 2020-08-06 17:25:54 · 2397 阅读 · 0 评论 -
C++学习笔记【七】—— 杂项运算符
C++运算符算术运算符关系运算符逻辑运算符位运算符赋值运算符杂项运算符其中杂项运算符如下:原创 2020-08-06 17:00:34 · 265 阅读 · 0 评论 -
C++学习笔记【六】—— 存储类
Auto声明变量时根据初始化表达式自动推断该变量的类型、声明函数时函数返回值的占位符。C++11已弃用。auto f=3.14; //doubleauto s("hello"); //const char*auto z = new auto(9); // int*auto x1 = 5, x2 = 5.0, x3='r';//错误,必须是初始化为同一类型register定义存储在寄存器中而不是 RAM 中的局部变量。这意味着变量的最大尺寸等于寄存器的大小(通常是一个词),且不能对原创 2020-08-06 16:45:47 · 242 阅读 · 0 评论 -
C++学习笔记【五】—— 修饰符类型
修饰变量修饰符 signed、unsigned、long 和 short 可应用于整型,signed 和 unsigned 可应用于字符型,long 可应用于双精度型。修饰符 signed 和 unsigned 也可以作为 long 或 short 修饰符的前缀。例如:unsigned long int。C++ 允许使用速记符号来声明无符号短整数或无符号长整数。您可以不写 int,只写单词 unsigned、short 或 unsigned、long,int 是隐含的。注意: 有符号数和无符号数原创 2020-08-05 11:09:38 · 244 阅读 · 0 评论 -
C++学习笔记【四】—— C++ 变量与常量
C++基本变量类型C++ 也允许定义各种其他类型的变量,比如枚举、指针、数组、引用、数据结构、类等等,这将会在后续的章节中进行讲解。变量声明当您使用多个文件且只在其中一个文件中定义变量时(定义变量的文件在程序连接时是可用的),变量声明就显得非常有用。您可以使用 extern 关键字在任何地方声明一个变量。虽然您可以在 C++ 程序中多次声明一个变量,但变量只能在某个文件、函数或代码块中被定义一次。字符串常量转义字符定义常量的两种方式在 C++ 中,有两种简单的定义常量的方式:使用 #de原创 2020-07-30 11:35:33 · 228 阅读 · 0 评论