IE盒子

搜索
查看: 109|回复: 1

Cherno C++学习笔记二

[复制链接]

3

主题

8

帖子

13

积分

新手上路

Rank: 1

积分
13
发表于 2022-12-1 15:51:07 | 显示全部楼层 |阅读模式
前言

本文主要是个人学习Cherno大神C++视频的学习笔记,以及个人按照视频取敲代码时的一些实践和理解,如有错误还请指正。以下是原视频 ,有需要的小伙伴可自行前往学习!
Variables in C++

C++中所有的变量类型最本质的区别就是所占内存空间不同,他们的本质均是将一个二进制数存储在指定的内存区域,而大部分操作系统按照字节(1Byte=8bit)寻址,所以这些变量所占内存空间的单位也均为字节。
#include <iostream>

int main() {
    int a = 1;
    short b = 2;
    /*char本身也是存储字符的ASCII码,仍为数字,A->65,只是在编译器进行解析时将其解析为字符(cout)
      因此其实char c = 65 与 char c = 'A'是等价的 */
    char c = 'A';
    long d = 10;
    long long e = 100;
    float f = 2.3f; //遵循IEEE754标准的16位浮点数,在C++语法中如果2.3之后不加f会默认作为double类型
    double g = 2.6; //遵循IEEE754标准的32位浮点数
    bool h = false;  //bool值在内存中占据一个字节,在该字节中只占据一位,用0来判断为false,除0之外均为true

    std::cout << sizeof(int) << std::endl;      //int   4字节
    std::cout << sizeof(short) << std::endl;    //short 2字节
    std::cout << sizeof(char) << std::endl;     //char  1字节
    std::cout << sizeof(long) << std::endl;     //long  4字节
    std::cout << sizeof(long long) << std::endl;//long long 8字节
    std::cout << sizeof(float) << std::endl;    //float 4字节
    std::cout << sizeof(double) << std::endl;   //double 8字节
    std::cout << sizeof(bool) << std::endl;     //bool   1字节

    std::cin.get();
}
以上几种变量是C++中最基础的变量类型,所有其他的变量类型或者对象都可以由上述基础类型组成。
Functions in C++

函数提高代码的复用性

C++中函数的使用是为了尽可能地提高代码地重复利用问题,往往一些通用的函数方法会作为一个项目的底层函数,比如Math.h中的大部分方法,绝大部分的函数将由返回值以及传递的参数组成,而当不需要返回值时则可以用void进行修饰。
#include <iostream>
//典型没有返回值的方法
void MultiplyAndLog(int a, int b)
{
    std::cout << a * b << std::endl;
}
//返回值为int的方法,必须要return int
int Add(int a, int b)
{
    return a + b;
}

int main() { //int main() 比较特殊,它不需要返回值,编译器默认会给其添加return 0
    MultiplyAndLog(2, 5);
    std::cout << Add(3,3) << std::endl;
    std::cin.get();
}
虽然函数会极大的提高代码的复用率,但同时要注意的是,当代码执行过程中频繁地调用函数在底层是应用Call Function的,他会产生一次中断并用堆栈空间来记录调用函数前的执行地址,若函数存在返回值还需要额外保存该返回值,其实也有一定性能上的消耗。
特殊的inline函数

内联函数在编译后并不会调用Call function是因为内联是直接将函数内的代码粘贴至代码执行的指定位置,但往往内联函数不能过于复杂
C++ Header Files

函数声明与函数定义

C++中的头文件是一种让人非常头疼的文件类型,要了解头文件首先要了解C++中Linker是怎么在不同cpp之间调用函数方法的。我们知道在一个庞大的项目中,我们是不可能将所有的函数方法写在一个cpp中的,但在任何一个cpp文件中可能需要调用其他cpp中的函数方法,此时我们需要将函数拆解为两部分,函数声明(declaration)与函数定义(definition)。
const char* Log(const char* message); //函数声明:只需要函数的返回值与传递的参数

const char* Log(const char* message) {//函数定义:函数的主体实现部分
    return message;
}
当我们将函数定义完成后,我们在任一个Cpp文件中加入函数声明,Linker就会找到对应Cpp中函数定义部分并调用该函数,那随着函数数量的增多,我们不可能将所有的定义写在一个Cpp文件中,此时便引入了头文件(Header Files),头文件的主要目的是用来进行函数声明,以及用来定义他自己的类或结构体。
//Log.h (进行函数声明)
#pragma once

const char* Log(const char* message);
void InitLog();


//Log.cpp (进行函数定义)
#include <iostream>
#include "Log.h"

const char* Log(const char* message) {
    return message;
}

void InitLog() {
    std::cout << Log("Init") << std::endl;
}

//Main.cpp
#include <iostream>
#include "Log.h" //引入头文件,其实也相当于把定义那块部分粘贴到Main.cpp中

int main() {
    InitLog();  //正确编译链接,并调用Log.cpp中InitLog()方法
    std::cin.get();
}
#pragma once

#pragma once是在头文件中最常见的预处理符号,他的作用是让在任意一个引用该头文件的cpp文件中,不会反复引用该头文件。
#include <iostream>
#include "Log.h"
#include "Log.h"  //#pragma once会在编译过程中只复制一次Log.h,类似Hash的方法

int main() {
    InitLog();
    std::cin.get();
}
若不使用这个预处理,当在头文件中定义结构体或类时就会出现重复定义的情况导致编译错误,同时#pragma once 是现代C++编译器做的一种优化,本质还是由最基本的#if实现
#ifndef _LOG_H
#define _LOG_H
const char* Log(const char* message);
void InitLog();
#endif
//上述定义就是#pragma once预处理的实现
#Include<>与#include""

#include" " 其实是更为通用的方式,他默认是使用项目的目录作为相对路径的,同时也可以修改相对路径去获取其他目录下的文件(#include "../GameDevelopmentLearning/Log.h" 这样也是可以的)


#include<>则是默认找到编译器的include文件夹,这里使用的是VS编译器,我们可以看一下iostream的默认位置在哪里(可以看到iostream文件实在vs编辑器内的include文件夹内的)。

回复

使用道具 举报

2

主题

9

帖子

16

积分

新手上路

Rank: 1

积分
16
发表于 2025-3-23 09:53:13 | 显示全部楼层
啊啊啊啊啊啊啊啊啊啊啊
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表