[自用]C++基础知识

参考自-菜鸟教程
这篇笔记用于已经学过c++的人复习使用,完全没有学过的请参考其他教程(╹ڡ╹ )

注释

有两种注释方法:

  • // - 一般用于单行注释。
  • /* … */ - 一般用于多行注释。
    代码示例:
#include <iostream>
using namespace std;
 
int main() {
  // 这是一个注释
  cout << "Hello World!";
  /* 这是注释 */
 
    /* C++ 注释也可以
     * 跨行
     */ 
  cout << "Hello World!";
  return 0;
}

左值(Lvalues)和右值(Rvalues)

  • 左值(lvalue):指向内存位置的表达式被称为左值(lvalue)表达式。左值可以出现在赋值号的左边或右边。
  • 右值(rvalue):术语右值(rvalue)指的是存储在内存中某些地址的数值。右值是不能对其进行赋值的表达式,也就是说,右值可以出现在赋值号的右边,但不能出现在赋值号的左边。

数据类型

各种类型的字节数
整数类型(Integer Types):
int:用于表示整数,通常占用4个字节。
short:用于表示短整数,通常占用2个字节。
long:用于表示长整数,通常占用4个字节。
long long:用于表示更长的整数,通常占用8个字节。
浮点类型(Floating-Point Types):
float:用于表示单精度浮点数,通常占用4个字节。
double:用于表示双精度浮点数,通常占用8个字节。
long double:用于表示更高精度的浮点数,占用字节数可以根据实现而变化。
字符类型(Character Types):
char:用于表示字符,通常占用1个字节。
wchar_t:用于表示宽字符,通常占用2或4个字节。
char16_t:用于表示16位Unicode字符,占用2个字节。
char32_t:用于表示32位Unicode字符,占用4个字节。
字符串类型
char[] / string
布尔类型(Boolean Type):
bool:用于表示布尔值,只能取true或false。
枚举类型(Enumeration Types):
enum:用于定义一组命名的整数常量。
指针类型(Pointer Types):
type*:用于表示指向类型为type的对象的指针。
数组类型(Array Types):
type[]或type[size]:用于表示具有相同类型的元素组成的数组。
结构体类型(Structure Types):
struct:用于定义包含多个不同类型成员的结构。
类类型(Class Types):
class:用于定义具有属性和方法的自定义类型。
共用体类型(Union Types):
union:用于定义一种特殊的数据类型,它可以在相同的内存位置存储不同的数据类型。
在这里插入图片描述
有七种基本数据类型

  • bool 1byte 存储值 true 或 false

  • char 1byte

  • int 4byte

  • float 4byte
    在这里插入图片描述

  • double 8byte
    在这里插入图片描述

  • void 1byte 表示类型缺失

  • wchar_t 2/4byte
    四种常用修饰符

  • signed 默认情况下,int、short、long都是带符号的,即 signed。

  • unsigned

  • short

  • long

其中wchar_t为short int定义而来

typedef short int wchar_t;

输出数据类型字节数和范围:

#include<iostream>  
#include <limits>
using namespace std;  
int main(){
	cout << "bool: \t\t" << "所占字节数:" << sizeof(bool); 
	cout << "\t最大值:" << (numeric_limits<bool>::max)();  
    cout << "\t\t最小值:" << (numeric_limits<bool>::min)() << endl;  
	return 0;
}

常量

区分:变量, 常量, 数据类型。

  • 数据类型定义了变量和常量的类型,它决定了存储的数据的种类和操作的方式。
  • 变量是程序中用于存储和表示可变数据的标识符。它们在程序执行期间的值可以被修改。
  • 常量是固定值,在程序执行期间不会改变。这些固定的值,又叫做字面量。

整数常量

  • 前缀指定基数:0x 或 0X 表示十六进制,0 表示八进制,不带前缀则默认表示十进制。
  • 整数常量也可以带一个后缀,后缀是 U 和 L 的组合,U 表示无符号整数(unsigned),L 表示长整数(long)。后缀可以是大写,也可以是小写,U 和 L 的顺序任意。
212         // 合法的
215u        // 合法的
0xFeeL      // 合法的
078         // 非法的:8 不是八进制的数字
032UU       // 非法的:不能重复后缀

浮点常量

  • 当使用小数形式表示时,必须包含整数部分、小数部分,或同时包含两者。3.14159
  • 当使用指数形式表示时, 必须包含小数点、指数。带符号的指数是用 e 或 E 引入的。 314159E-5L
85         // 十进制
0213       // 八进制 
0x4b       // 十六进制 
30         // 整数 
30u        // 无符号整数 
30l        // 长整数 
30ul       // 无符号长整数

布尔常量
布尔常量有两个:

  • true 可以隐式转换为1
  • false 可以隐式转换为0

字符常量
字符常量是括在单引号中。如果常量以 L(仅当大写时)开头,则表示它是一个宽字符常量(例如 L’x’),此时它必须存储在 wchar_t 类型的变量中。否则,它就是一个窄字符常量(例如 ‘x’),此时它可以存储在 char 类型的简单变量中。
字符常量可以是一个普通的字符(例如 ‘x’)、一个转义序列(例如 ‘\t’),或一个通用的字符(例如 ‘\u02C0’)。

字符串常量
字符串常量是括在双引号 “” 中的。一个字符串包含类似于字符常量的字符:普通的字符、转义序列和通用的字符。
可以使用 \ 做分隔符,把一个很长的字符串常量进行分行。

"he\
llo"

定义常量

  • #define identifier value :#define LENGTH 10
  • const type variable = value;: const int LENGTH = 10;

把常量定义为大写字母形式,是一个很好的编程实践。

变量定义

变量定义的赋值是可选项

type variable_list;
type variable_name = value;

variable_list 可以由一个或多个标识符名称组成,多个标识符之间用逗号分隔。下面列出几个有效的声明:

int    i, j, k;
char   c, ch;
float  f, salary;
double d;
extern int d = 3, f = 5;    // d 和 f 的声明 
int d = 3, f = 5;           // 定义并初始化 d 和 f
byte z = 22;                // 定义并初始化 z
char x = 'x';               // 变量 x 的值为 'x'

变量声明

声明使用extern关键字。
声明(Declaration):

  • 目的: 用于告诉编译器变量的类型和名称,但不分配存储空间。
  • 示例: extern int x;
  • 说明: 这告诉编译器在程序的其他地方存在一个名为 x 的整数变量,但并没有为其分配实际的内存空间。这通常用于在不同的文件中共享变量。

定义(Definition):

  • 目的: 声明的同时为变量分配内存空间。
  • 示例: int y;
  • 说明: 这行代码不仅告诉编译器 y 是一个整数,还为 y 分配了实际的内存空间。变量的定义意味着程序已经准备好使用这个变量了。
    在实际编程中,通常会将声明和定义合并在一起。例如:
#include <iostream>

extern int x; // 声明

int main() {
    int y; // 定义
    std::cout << "Hello, World!" << std::endl;
    return 0;
}

变量作用域

有三种变量:

  1. 局部变量:在函数或一个代码块内部声明的变量
  2. 形式参数
  3. 全局变量
#include <iostream>
int a;//全局变量
int main() {
    int a = 10;//局部变量
    {
        int a = 20;  // 块作用域变量
        std::cout << "块变量: " << a << std::endl;
    }
    std::cout << "局部变量: " << a << std::endl;
    return 0;
}

有四种作用域:
1.局部作用域:在函数内部声明的变量具有局部作用域,它们只能在函数内部访问。局部变量在函数每次被调用时被创建,在函数执行完后被销毁。

2.全局作用域:在所有函数和代码块之外声明的变量具有全局作用域,它们可以被程序中的任何函数访问。全局变量在程序开始时被创建,在程序结束时被销毁。

3.块作用域:在代码块内部声明的变量具有块作用域,它们只能在代码块内部访问。块作用域变量在代码块每次被执行时被创建,在代码块执行完后被销毁。

4.类作用域:在类内部声明的变量具有类作用域,它们可以被类的所有成员函数访问。类作用域变量的生命周期与类的生命周期相同。
如果在内部作用域中声明的变量与外部作用域中的变量同名,则内部作用域中的变量将覆盖外部作用域中的变量。

当局部变量被定义时,系统不会对其初始化。定义全局变量时,系统会自动初始化为下列值:
在这里插入图片描述

typedef 声明

下面的语句会告诉编译器,feet 是 int 的另一个名称:

typedef int feet;
feet distance;

枚举

如果一个变量只有几种可能的值,可以定义为枚举(enumeration)类型。

enum 枚举名{
标识符[=整型常数],
标识符[=整型常数], …
标识符[=整型常数] } 枚举变量;

如果枚举没有初始化, 即省掉"=整型常数"时, 则从第一个标识符开始。

例如,下面的代码定义了一个颜色枚举:

int main(){
	enum color { red, green, blue } c;
	c = blue;
	color b = red;
	cout<<c//2
	if (b==red){
		cout<<"b is red";}//b is red
	return 0;
}

存储类

static

  • 修饰局部变量:局部变量的生命周期为程序的生命周期,但作用域仍然是函数内部。它在程序启动时初始化,仅在第一次函数调用时分配内存,然后在整个程序运行期间保持其值,并在程序结束时销毁。
  • 修饰全局变量:变量的作用域在文件内
  • 修饰类的成员:所有对象共享成员

extern

  • 全局变量声明:A头文件声明A.cpp全局变量+B.cpp引用头文件/B.cpp声明A.cpp全局变量= = = ==》B.cpp可以直接使用A.cpp的全局变量
  • 局部变量声明:局部变量不能被外部文件使用
  • 外部函数声明(可以不使用extern关键字):A头文件声明A.cpp函数+B.cpp引用头文件/B.cpp声明A.cpp函数= = = ==》B.cpp可以直接使用A.cpp的函数
  • 防止多个文件重复定义相同的全局变量:多个文件声明相同的全局变量会报错。

mutable

mutable 说明符仅适用于类的对象。它允许对象的成员替代常量。

thread_loacal

使用 thread_local 说明符声明的变量仅可在它在其上创建的线程上访问。 变量在创建线程时创建,并在销毁线程时销毁。 每个线程都有其自己的变量副本。

运算符

位运算符:

对于A = 0011 1100

  • &:与
  • | :或
  • ~:非
  • ^: 异或
  • <<:二进制左移运算符。将一个运算对象的各二进制位全部左移若干位(左边的二进制位丢弃,右边补0)。
  • :二进制右移运算符。将一个数的各二进制位全部右移若干位,正数左补0,负数左补1,右边丢弃。

杂项运算符

在这里插入图片描述

循环

for /while,没什么要点
循环控制要了解一下:
在这里插入图片描述

判断语句

1.if····· else·····
2.switch
基本语法:

switch(expression){
    case constant-expression  :
       statement(s);
       break; // 可选的
    case constant-expression  :
       statement(s);
       break; // 可选的
    // 您可以有任意数量的 case 语句
    default : // 可选的
       statement(s);
}
  • switch 语句中的 expression 必须是一个整型或枚举类型,或者是一个 class 类型,其中 class 有一个单一的转换函数将其转换为整型或枚举类型。
  • 当遇到 break 语句时,switch 终止,控制流将跳转到 switch 语句后的下一行。
  • 不是每一个 case 都需要包含 break。如果 case 语句不包含 break,控制流将会 继续 后续的 case,直到遇到 break 为止。
  • 一个 switch 语句可以有一个可选的 default case,出现在 switch 的结尾。default case 可用于在上面所有 case 都不为真时执行一个任务。default case 中的 break 语句不是必需的。
    一个例子:
#include <iostream>
using namespace std;
 
int main ()
{
   // 局部变量声明
   char grade = 'D';
 
   switch(grade)
   {
   case 'A' :
      cout << "很棒!" << endl; 
      break;
   case 'B' :
   case 'C' :
      cout << "做得好" << endl;
      break;
   case 'D' :
      cout << "您通过了" << endl;
      break;
   case 'F' :
      cout << "最好再试一下" << endl;
      break;
   default :
      cout << "无效的成绩" << endl;
   }
   cout << "您的成绩是 " << grade << endl;
 
   return 0;
}

您通过了
您的成绩是 D

函数

  • 每个 C++ 程序都至少有一个函数,即主函数 main()
  • 函数声明:如果在调用前函数已经定义,则不必再写函数的声明了

函数声明包括以下几个部分:

return_type function_name( parameter list );

例如

int max(int num1, int num2=20);//指定了默认值
// 在函数声明中,参数的名称并不重要,只有参数的类型是必需的,因此下面也是有效的声明:
int max(int, int);

函数参数
在这里插入图片描述

函数修饰符

修饰符一般位于函数后,也有一些特殊的位于函数前,如virtual用于修饰虚函数。

返回类型 函数名(参数列表) 修饰符;

  • const修饰符:**用于修饰成员函数,**表示函数不会修改对象的成员变量
class Myclass{
public:
int i;//i不能被constFunction()修改
void constFunction() const {
        // 不可以修改成员变量
    }
    }
  • throw()修饰符表示函数不会抛出异常

Lambda 函数与表达式/匿名函数

看不懂·····哈哈/跳过

数组

数组名代表数组的第一个元素的地址,是一个指针常量,其值不能改变。

nclude <iostream>
 
using namespace std;
const int MAX = 3;
 
int main ()
{
   int  var[MAX] = {10, 100, 200};
   int  *ptr;
 
   // 指针中的数组地址
   ptr = var;
   for (int i = 0; i < MAX; i++)
   {
      cout << "var[" << i << "]的内存地址为 ";
      cout << ptr << endl;
 
      cout << "var[" << i << "] 的值为 ";
      cout << *ptr << endl;
 
      // 移动到下一个位置
      ptr++;
   }
   return 0;
}

数组名是一个指向数组第一个元素的指针常量。常量不能作为左值,因此不能使用++运算符

#include <iostream>
 
using namespace std;
const int MAX = 3;
 
int main ()
{
   int  var[MAX] = {10, 100, 200};
 
   for (int i = 0; i < MAX; i++)
   {
      *var = i;    // 这是正确的语法
      var++;       // 这是不正确的
   }
   return 0;
}

字符串

c风格

字符串实际上是使用 null 字符 \0 终止的一维字符数组。

char site[7] = {'R', 'U', 'N', 'O', 'O', 'B', '\0'};
char site[] = "RUNOOB";
char site[6] = {'R', 'U', 'N', 'O', 'O', 'B'};这并不是一个字符串,而是一个字符数组

操纵字符串的函数:
在这里插入图片描述

string 类

C++ 标准库提供了 string 类类型

#include <iostream>
#include <string>
 
using namespace std;
 
int main ()
{
   string str1 = "runoob";
   string str2 = "google";
   string str3;
   int  len ;
 
   // 复制 str1 到 str3
   str3 = str1;
   cout << "str3 : " << str3 << endl;
 
   // 连接 str1 和 str2
   str3 = str1 + str2;
   cout << "str1 + str2 : " << str3 << endl;
 
   // 连接后,str3 的总长度
   len = str3.size();
   cout << "str3.size() :  " << len << endl;
 
   return 0;
}

指针

指针是一个变量类型,其值为另一个变量的地址,指针可以改变。
数组名是一个指针常量,其值是数组第一个元素的地址,数组名的值不能改变。

引用

引用是&,指针是*

引用很容易与指针混淆,它们之间有三个主要的不同:

  • 不存在空引用。引用必须连接到一块合法的内存。
  • 一旦引用被初始化为一个对象,就不能被指向到另一个对象。指针可以在任何时候指向到另一个对象。
  • 引用必须在创建时被初始化。指针可以在任何时间被初始化。
int i = 17;
int&  r = i;
double& s = d;

引用通常用于函数参数列表和函数返回值。在这里插入图片描述

io

  • 标准输入流(cin)
cin >> name >> age;
  • 标准输出流(cout)
cout << "您的名称是: " << name << endl;
  • 标准错误流(cerr):非缓冲
cerr << "Error message : " << str << endl;
  • 标准日志流(clog):缓冲
clog << "Error message : " << str << endl;

结构体

  • 定义:
struct type_name {
member_type1 member_name1;
member_type2 member_name2;
member_type3 member_name3;
.
.
} object_names;
  • 示例:
struct Books
{
   char  title[50];
   char  author[50];
   char  subject[100];
   int   book_id;
} book;
  • 为了访问结构的成员,我们使用成员访问运算符(.)
cout<<book.title
  • 指向结构的指针,访问成员时使用成员访问运算符(->)
struct Books *struct_pointer;
struct_pointer = &book;
cout<<struct_pointer->title;
  • typedef 关键字,可以为结构体取一个别名
typedef struct *Books
{
   char  title[50];
   char  author[50];
   char  subject[100];
   int   book_id;
} Bookptr;
Bookptr struct_pointer; 
cout<<struct_pointer->title;

unordered_set

unordered_set使用哈希表实现,有几种常用的方法:

  • 创建:unordered_set<数据类型> visited;
  • 插入:visited.insert(temp);
  • 是否有某个元素:visited.count(temp),返回值0/1
  • 23
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值