C++(一)

前言

以前学习的C++忘得差不多了,因此重新学习一下并完善一下以前不理解的知识内容.大部分内容来自OI wiki,更完整内容可以前去观看链接.


以以下代码为例

#include <iostream>  // 引用头文件

using namespace std;

// 引入命名空间(相关阅读 https://oi-wiki.org/lang/namespace/#using )

int main() {                // 定义 main 函数
  cout << "Hello, world!";  // 输出 Hello, world!
  return 0;                 // 返回 0,结束 main 函数
}

#include

include是一个预处理命令,include<>尖括号里面为一个头文件,程序编译时将头文件内的内容链接到程序里编译(如cin,cout,printf等)


using namespace std;

意为使用一个名为std的空间名.
std为C++的命名空间,引入命名空间的目的是解决复杂项目中名字的冲突问题.例如:
假设自己定义了一个cin变量,但是std库中也含有cin,那么我们可以使用如下方式解决冲突

#include<iostream>
//此处无using namespace std;因为我们不希望使用std命名空间使得cin定义冲突
int main(){
	定义cin
	cin....//使用自己定义的cin
	std::cin<<....//使用std中的cin
	.....
	return 0;
}

int main()

main是一个程序的入口.,程序执行或者调用时仅执行或调用main函数

高级数据结构

数组

定义:(int,char,long,bool,double,flat....) a[Num][Num] .
int a[100]定义一个长度为100的整数数组(下标从0~99).
多维数组:char [100][100]
注意:过大数组尽量使用全局变量,局部变量会放在动态区(栈区)可能会造成溢出.
全局变量则会放在静态区未引用时仅使用空间.

结构体

定义:

struct Object{
	int learn;
	int point;
}MAP[100];

结构体的主要作用是将变量捆绑在一起.
值得注意的是,结构体在储存时可能存在实际大小比定义大小更大
原因如下:

为了访问内存的效率更高,编译器在处理结构中成员的实际存储情况时,可能会将成员对齐在一定的字节位置,也就意味着结构中有空余的地方。因此,该结构所占用的空间可能大于其中所有成员所占空间的总和。

指针

指针,即只想储存地址的特殊变量.用途极广(同时也很难).
指针变量的定义:
类型名后加*.如int* a;
要想访问指针变量地址所对应的空间(又称指针所 指向 的空间),需要对指针变量进行 解引用(dereference),使用 * 符号。

int main() {
  int a = 123;  // a: 123
  int* pa = &a;
  *pa = 321;  // a: 321
}

对结构体变量也是类似。如果要访问指针指向的结构中的成员,需要先对指针进行解引用,再使用 . 成员关系运算符。不过,更推荐使用“箭头”运算符 -> 这一更简便的写法。

struct ThreeInt {
  int a;
  int b;
  int c;
};

int main() {
  ThreeInt x{1, 2, 3}, y{6, 7, 8};
  ThreeInt* px = &x;
  (*px) = y;    // x: {6,7,8}
  (*px).a = 4;  // x: {4,7,8}
  px->b = 5;    // x: {4,5,8}
}

指针的偏移

指针变量也可以 和整数 进行加减操作。对于 int 型指针,每加 1(递增 1),其指向的地址偏移 32 位(即 4 个字节);若加 2,则指向的地址偏移 2 × 32 = 64 位。同理,对于 char 型指针,每次递增,其指向的地址偏移 8 位(即 1 个字节)。
使用指针偏移访问数组
我们前面说过,数组是一块连续的存储空间。而在 C/C++ 中,直接使用数组名,得到的是数组的起始地址。

int main() {
  int a[3] = {1, 2, 3};
  int* p = a;  // p 指向 a[0]
  *p = 4;      // a: [4, 2, 3]
  p = p + 1;   // p 指向 a[1]
  *p = 5;      // a: [4, 5, 3]
  p++;         // p 指向 a[2]
  *p = 6;      // a: [4, 5, 6]
}

关于指针更进阶的应用可访问(OI Wiki)[https://oi-wiki.org/lang/pointer/]
本文的大部分内容均来自此网站.

文件操作

  1. freopen
    FILE* freopen(const char* filename, const char* mode, FILE* stream);
  • filename 要打开的文件名
  • mode 文件打开方式(文件访问权限)
  • stream 文件指针,通常使用标准文件流 (stdin/stdout) 或标准错误输出流 (stderr)
    常用mode:
  • r:只读,文件必须存在
  • w:只写,文件必须存在
  • r+:读/写,文件必须存在
  • w+:读/写,文件不存在则新建文件,否则清空后写入.
    其他:
  • rb:只读打开二进制文件,文件必须存在
  • wb:只写打开二进制文件,文件不存在则新建文件,否则清空后写入.
  • rb+:读/写打开二进制文件,文件必须存在
  • wb+:读/写打开二进制文件,文件不存在则新建文件,否则清空后写入.
  • a:以附加方式打开只写文件,文件不存在将新建文件,写入数据将被附加在文件末尾(保留 EOF 符)
  • a+:以附加方式打开只写文件,文件不存在将新建文件,写入数据将被附加在文件末尾(不保留 EOF 符)
  • at+:以读写方式打开文本文件,写入数据将被附加在文件末尾
  • ab+:以读写方式打开二进制文件,写入数据将被附加在文件末尾
    例子:
#include <cstdio>
#include <iostream>

int main(void) {
  freopen("data.in", "r", stdin);
  freopen("data.out", "w", stdout);
  /*
  中间的代码不需要改变,直接使用 cin 和 cout 即可
  */
  fclose(stdin);
  fclose(stdout);
  return 0;
}
posted @ 2022-07-29 16:39  小何家的博客  阅读(59)  评论(0编辑  收藏  举报