【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 窄向转换(不安全)

扫描二维码关注公众号,回复: 17517110 查看本文章

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