【Unreal】Unreal学习笔记一

目录

一、准备工作(C++方面)

1.1 VisualStudio设置

1.2 C++程序的编译流程

1.2.1 预处理——Preprocess

1.2.2 编译——Compile

1.2.3 汇编——Assemble

1.3 类型转换

1.3.1 宽向转换(绝对安全)

1.3.2 窄向转换(不安全)

1.3.3 宽度表格

1.4 头文件

1.5 指针

1.5.1 指针的基本

1.5.2 常量指针,指针常量与常指针常量

1.5.2.1 常量指针(经常使用)

1.5.2.2 指针常量(不常用)

1.5.2.3 常指针常量

1.5.3 void 关键字

1.5.4 空指针(0 或 NULL)

1.5.5 野指针

 1.5.6 数组

1.5.7 函数指针


一、准备工作(C++方面)

1.1 VisualStudio设置

桌面开发 + 用C++开发游戏 ——> 下载并安装需要的组件

1.2 C++程序的编译流程

        06-编译的四个阶段_哔哩哔哩_bilibili

1.2.1 预处理——Preprocess

去掉注释,展开include

1.2.2 编译——Compile

将预处理阶段的代码转为汇编语言

1.2.3 汇编——Assemble

将汇编转为机器语言

将程序不同部分合并在一起形成可执行文件

1.3 类型转换

        09-类型转换_哔哩哔哩_bilibili

1.3.1 宽向转换(绝对安全)

低宽度转为高宽度(例如:char 类型的宽度是8位, 转为short类型16位)

1.3.2 窄向转换(不安全)

高宽度转为低宽度

1.3.3 宽度表格

​ 1、编译系统给int型数据分配的内存可能是2个字节或是4个字节,具体由编译系统自行决定。例如:Turbo C 2.0分配的是2个字节,而Visual C++则分配4个字节。

​ 2、在编程考虑数据规模时,如果记不清楚具体数值范围,可根据十进制位数来决定使用什么类型。例如:当需要存储一个大小为100 000 000 0的数时,可以选择大于等于10位十进制数范围的类型,如long、long long 等。

Integer types:

Name Size(in bits, on x86) Range
bool 8 (top 7 bits are ignored) o or 1
char 8 -128 to 127(signed) or 0-255(unsigned)
short 16 -32768 to 32767(signed) or 0-65535(unsigned)
int    32 -2147483648 to 2147483647(signed) or 0-4294967295(unsigned)
long 32(can be 64 on other architectures)

same as int

long long 64(this is a non-standard GNU extension) -9223372036854775808 to 9223372036854775807(signed) or 0-18446744073709551615


Floating Point type: 

Name Size(int bits,on x86) Range Notes
float 32 +/-1.4023x10^{-45} to 3.4028x10^{38} general purpose real-number
double 64 +/-4.9406x10^{-324} to 1.7977x10^{308} higher-precision real number
long double 96(this is a non-standard GNU extention) ?? For numbers with very large ranges and high precision

1.4 头文件

        6-使用头文件_哔哩哔哩_bilibili

一个放函数声明的地方。

//函数声明
int Add(int);int Main
{}
//函数定义
int Add(int)
{
}

声明: 告诉编译器,有一个名字Add,返回值和参数需要int的函数

定义: 在内存中拓展出一片空间给该函数分配内存

声明是不开辟内存空间,而定义必须占用内存空间

在C#中定义一个函数后可以直接进行使用,而不用在主体函数体上方声明函数

1.5 指针

1.5.1 指针的基本

        为什么C++既有指针又有引用 | 指针和引用的区别 |_哔哩哔哩_bilibili

具有自己的标识,程序员可见的内存地址,可测量的内存大小。

引用自带非空语义。

&: 取地址运算符

*:间接运算符或取消引用运算符(其实就是取值)

好!人已经开始晕了。刚看到函数指针, 指针函数, 指针的指针。。。

只需8分钟,理解指针很轻松!!!手写代码加画图。c/c++的灵魂指针!!_哔哩哔哩_bilibili

int a;
int *b;            //指针变量, 存储地址 
int a = 5;
b = &a;            // 取a的地址赋值给b 那么在b的地址上存储的是a的地址


//--------------------------------------
// 此时: 输出
cout << a;          // 5
cout << &a;         // 存a的地址 (0x123)
cout << b;          // 由于b存的是a的地址, 所以值是 a的地址(0x123)
cout << *b;         // 取这个指针变量, 也就是该指针指向a的变量: 5

// 当*与&同时存在(即*&a)时抹消两个符号,即 *&a = a

// 若修改*b则a的值也会发生变化
*b = 10;
cout << a;          // 输出为10


//---------------------------------------
// 数组名 = 数组的首地址 即 arr = &arr[0]
  • 下方有解释指向指针的指针,  但是这种多层指针一般不会用到, 指针最常见的用途是构造数据结构和操作内存

        是不是一直搞不懂C语言的指针,看完这个动画,你就全明白了_哔哩哔哩_bilibili

  • 在64位的操作系统中, 不管是什么类型的指针, 占用的内存都是8字节。 
  • 在32位的操作系统中, 不管是什么类型的指针, 占用的内存都是4字节。 
1.5.2 常量指针,指针常量与常指针常量

        用const修饰指针_哔哩哔哩_bilibili

1.5.2.1 常量指针(经常使用)
  • 语法: const 数据类型 *变量名
  • 常量指针不能通过解引用的方法修改内存地址中的值(用原始的变量名是可以修改的)
1.5.2.2 指针常量(不常用)
  • 语法: 数据类型 *const 变量名
  • 指向的变量(对象)不可改变
  • 在定义时必须初始化
  • 可通过解引用的方法修改内存地址中的值
  • C++编译器将指针常量做了特别处理后,改名引用
1.5.2.3 常指针常量
  • 语法: const 数据类型 *const 变量名
  • 指向的变量(对象)不可改变, 不能通过解引用的方法修改内存地址中的值
  • 新名字——常引用

常量指针: 指针指向可以改, 指向的值不可修改

指针常量: 指针指向不可更改, 指向的值可以改

常指针常量: 指针指向不可更改, 指针指向的值不可更改

1.5.3 void 关键字

void关键字_哔哩哔哩_bilibili

  • void * 表示接受任意类型的指针, 只关心地址本身, 不关心里边的内容
  • 不能用void声明变量, 它不能代表一个真实的变量
  • 不能对void *指针直接解引用(需要转换成其他类型的指针)
  • 把其他类型的指针赋值给void *指针不需要转换
  • 把void *指针赋值给把其它类型的指针需要转换
  • 刚开始看到它可能不习惯, 以后每天都能看到它, 看多了就熟了
1.5.4 空指针(0 或 NULL)
  • 对空指针解引用, 程序会崩溃
  • 对空指针使用delete运算符, 系统会忽略该操作, 不会出现异常。所以内存释放后, 也应把指针指向空
  • 在函数中, 应该有判断形参是否为空指针的代码, 目的是保证程序的健壮性
  • C++11建议用nullptr表示空指针, 也就是 (void *)0.
    • 在Linux平台下, 如果使用 nullptr , 编译需要加 -std=c++11参数
1.5.5 野指针
  • 指针指向的不是一个有效(合法)的地址
  • 如果访问野指针,可能会造成程序的崩溃
  • 出现野指针的情况有三种
    • 指针在定义时没有初始化,它的值是不确定的
    • 如果用指针指向了动态分配的内存,内存被释放后指针不会置空,但是指向的地址已失效
    • 指针指向的变量已超越变量作用域(变量内存空间已被系统回收)
    • int *func()
      {
          int a = 3;
          
          return &a;
      }
      
      *int main()
      {
          int *p = func();
      }
  • 规避方法
    • 指针在定义的时候,如果没有地方指就初始化为 nullptr
    • 动态分配的内存被释放后,将其置为 nullptr
    • 函数不要返回局部变量的地址
    • 使用智能指针
 1.5.6 数组

一维数组用于函数的参数_哔哩哔哩_bilibili

  • 指针的数组表示
    • C++ 编译器把 数组名[下标] 解释为 *(数组首地址 + 下标)
    • C++编译器把 地址[下标] 解释为 *(地址 + 下标)
      • ​​​​​​​​​​​​​​这种方式就可以理解为 p[3] == a[3]。 p[3] == *(p + 3) 
      • int a[5] = {3, 6, 5, 8, 9};
        
        int *p = a;
    •  一维数组用于函数的参数时,只能传数组的地址,并且必须把数组长度也传进去,除非数组中有最后一个元素的标识
    • 动态创建一维数组语法: 数据类型 *指针 = new 数据类型[数组长度];
    • 释放语法: delete[] 指针;
    • 动态创建的数组没有数组名,不能用 sizeof 运算符
    • 可以用数组表示法和指针表示法两种方式使用动态创建的数组
    • 必须使用 delete[] 来释放内存(不能只用 delete)
      • delete只会释放第0个元素的内存空间
    • 不要用 delete[] 来释放不是 new[] 分配的内存
    • 不要用 delete[] 释放同一个内存块两次(否则等同于操作野指针)
    • 对空指针用 delete[] 是安全的(释放内存后应该把指针置空 nullptr)
    • 声明普通数组时数组长度可以用变量,相当于在栈上动态创建数组,并且不需要释放
    • 如果内存不足,调用new会产生异常,导致程序终止,如果在new关键字后加(std::nothrow)选项,则返回 nullptr ,不会产生异常
    • int main()
      {
          int *a = new (std::nothrow) int[1000000001];
      
          if(a == nullptr)
          {
              return;
          }
          else
          {
              a[1000000000] = 8;
              delete[] a;
          }
      }

    • 由于系统会自动跟踪已分配的内存,所以 delete[] 释放数组的时候不需要指定数组大小
    • 指针是指针,地址是地址,指针是一个容器,用于存放地址
1.5.7 函数指针
  • 声明函数指针
  • 让函数指针指向函数的地址
  • 通过函数指针调用函数
  • (有点像c#中的委托)
    void func(int no, string str)
    {
        
    }
    
    int main()
    {
        int bh = 3;
        string message = "1111"
        func(bh, message);
        
        void (*pfunc)(int, string);
        pfunc = func;
        pfunc(bh, message);
    }

猜你喜欢

转载自blog.csdn.net/ViYeye/article/details/133160659