Golang入门学习(2)
Go的第二课——Go的特性&变量
Go的一些特性这次又学了点特性就是:
如果引入的包在文件中没有被用到则会导致编译通不过,这一点比较匪夷所思了,因为很多语言都没有这种限制。
同样,变量也有这个限制,定义的变量没有使用过也会报错。
入口函数为 main 函数
源文件必须 .go 为后缀
大小写敏感的语言
标准api文档在线:https://studygolang.com/pkgdoc(PS:这玩意可以直接保存下来离线观看)
Go的变量基础用法和注意事项每个编程语言最基本的单位就是变量了,那来看看 go 的一个定义和操作变量的方法吧。
基本数据类型
整数型((u)int(默认是64位),(u)int8,(u)int16,(u)int32,(u)int64,byte)
浮点类型(float(默认是float64),float32,float64)
字符型(没有专门的数据类型,一般使用 byte)
布尔型(bool)
字符串(string)
派生/复杂数据类型
指针(pointer)
数组([])
结构体(struct)
管道(Channel)
函数(func)
切 ...
Golang入门学习(1)
Go的第一课——简介&开发环境安装
最近完成了 C++ 的基础内容,其它的内容也要跟上来了,今天学学 go。
Go简介Go 是由 罗伯特·格瑞史莫、罗勃·派克及肯·汤普逊于2007年9月开始设计的语言,2009年11月正式宣布推出,静态强类型、编译型,高并发,并且具有垃圾回收机制的语言。
SDK安装点我跳转到下载页面
用 windows installer 可以一键配置环境变量,go 语言的编译器就叫 go,语言文件的后缀也是(.go)。
编译常用选项
build:编译一个可执行文件,-o 指定文件名,若不指定则默认与源文件一致。
run:直接运行一个 go 文件
编译执行eg1.
1go build main.go
编译 main.go 文件并生成 main.exe(windows)
eg2.
1go build main.go -o hello.exe
编译 main.go 文件并生成 hello.exe
eg3.
1go run main.go
直接运行 main.go 中的语言脚本
Go的一些特性
每个 go 文件必须属于一个包(package)
语句可 ...
C++的一些特性(4)
C++的一些特性(4)
C++的内存管理内存泄露在普通的 C 语言程序中。我们可以使用 malloc 函数动态地分配内存,然而若我们没有及时地对使用完成的内存进行释放,就会造成内存泄露。
来看下面的一个例子
1234567891011121314#include <stdio.h>#include <stdlib.h>void f(void){ void* s; s = malloc(50); return;}int main(void){ while (true) f(); /* Malloc函数迟早会由于内存泄漏而返回NULL*/ return 0;}
我们平时在用 PC 的时候可能没有任何感觉,毕竟如果占用内存过多我们关掉这个程序,甚至说重启一下电脑,肯定就没有这个问题了。但是内存泄露往往不发生在 PC 当中,而是会在服务器上,而服务器中运行的服务一般是常驻程序,一般情况下进程不允许被关闭更不允许随便重启,因此若服务的进程存在上述的内存泄露则迟早会耗尽服务器的内存资源。
智能指针C ...
C++的一些特性(3)
C++的一些特性(3)
列表初始化用一对大括号可以给一个数组,结构体,甚至是对象成员初始化。
数组1234567#include<iostream>using namespace std;char s[] = {'x','i','a','0','j','i','2','3','3'};int main() { puts(s); system("pause");}
结构体初始化,传参,返回都可以。
初始化结构体1234567891011#include<iostream>using namespace std;typedef struct __Info { int a; double b;}Info, * PInfo;int main() { Info s = & ...
C++的一些特性(2)
C++的一些特性(2)
左值和右值概念这两个概念其实就涉及到我们的赋值和引用。左值直观的理解就是在等号左边的值,右值就是出现在等号右边的值。左值一定是占据了内存中一个可识别的位置的,而右值则不一定有。
比较容易混淆的两个例子可能是
12x++;++x;
其中,x++ 是右值,++x 是左值。
也很好理解,我们在重载前置 ++ 的时候,是先加再返回,这个时候我完全可以给它加上之后返回一个原对象。但是后置 ++ 则不行,我需要先给它保存原对象,然后原对象++,返回刚刚保存的对象。
函数返回值一般情况下为右值,少数情况下,比如在定义返回值的时候类型加了引用(&),那么得到的值可能是左值。判断是否为左值很简单,在该值之前加一个 & 看看能否取出一个地址来。
左值引用和右值引用左值引用写法:
12int a=1;int &b=a;
引用其实前面介绍过了,就是绑定一个对象,让我对引用对象操作与实际被绑定的对象操作没有任何区别,也就是说在执行完 int &b=a 之后,a 和 b 变量没有区别的,都是操作同一块内存。
左值引用在执行的时候它的对象必须是一个左值 ...
C++的一些特性(1)
C++的一些特性(1)
这一章讲一下 C++ 比 C 多的一些东西吧,不然有时候真的感觉 C 和 C++ 区别不大的。
一些其它的函数定义内联函数内联函数是指在调用的时候不使用 call,而是用函数的代码替换这里的函数调用,可以节省这里时间上的效率损失,常见于逻辑简单,需要频繁调用的函数,这里省下的时间开销就很大,在函数定义前加关键字 inline 可以把函数声明为内联。当然,逻辑复杂的函数也可以使用 inline,但是编译器不一定会听,编译器会综合考虑要不要对这个函数使用内联。
裸函数在函数定义前加关键字 __deplspec(naked) 可以把函数声明为裸函数,裸函数是指什么都不具备的函数,不会自动给你压栈,也不会自动给你返回,什么都需要自己做。
一般来说,使用naked函数时需要注意以下问题:
函数必须显式返回。一般通过 __asm ret的内嵌汇编指令返回。
不可以通过任何方式使用局部变量。若声明一个局部变量,并在代码中为其赋值,则会更改父函数中相应位置的局部函数的值。
只能通过esp引用参数。因为子函数继承了父函数的ebp寄存器,所以只能通过esp引用参数。
nake ...
RCTF2022-MyCarsShowSpeed
做到一道好题,mark一下。
正向分析这一步是可以看看程序具体实现了一个什么逻辑,运行出现一个菜单,并且是多级的。
开始一把游戏
查看信息
拜访商店
切换卡车
输出一句话
退出
其中拜访商店又有一个新的菜单
买东西
卖东西
修车
取车
退回上一级
我们可以去商店买车,买汽油,买安全带(没有实际用处)和flag,当然 flag 比较贵,那么我们一定要寻找赚钱的途径,把车买了再卖了是得到一半的价格。修车根据时间来算价格,增加车的 health,车有 health,fuel,stability这几个属性,fuel是汽油,health 是血条吧可以理解为,另一个查一查单词意思是稳定性,不过也不知道具体是什么意思。
我们修车的时候不能卖车,估计是防止我们通过这个不停地卖车刷钱。
有了车我们可以去跟一个 bot pk,赢了的话得到 10 块钱,但是跑一次会损耗汽油和 health,然后又要去买,而且只赚 10 块,目测不行,但是通过正向的分析我们很浅显地知道了程序大概逻辑,具体实现需要分析它给的源码。
源码分析基本分析看到 .h 文件的一些结构体定义
12345678910111213 ...
C++基础——函数与类模板的一些细节
C++基础——函数模板与类模板的一些细节
这里做一下总结 and 深入吧~
类模板继承这里我们需要知道一点,模板类可以被继承,但是你必须指定类继承,比如你声明了一个
12345class A<T>{public: A(); ~A();}
A 并不是一个类,不能被继承,你只能继承一个 A<int> 类,或者是其它类的一个类实例,或者如果你想让子类也保持为泛型,那么你可以给子类定义一个模板类,然后这里继承的时候给 A<T>。
这里两种继承还是有很大区别的,至少在编译部分就会让你产生写法上的很大的差异,指定实例化的类继承这个我们很好理解,它就相当于直接指定完整了一个类,你把你指定的类用模板类替换上去类型就成了一个具体的类,然后去继承,和直接继承没有任何差别,我们主要关心第二种情况:子类传泛型进去给父类继承。
关注以下的代码:
12345678910111213141516171819202122232425262728293031#include<iostream>template<typenam ...
C++基础——函数与类模板
C++基础——函数模板与类模板
应该就是 C++ 的一个泛型编程了。
泛型编程泛型编程主要是因为这样的一个应用场景:如果我要实现一个数的加法,那么数可以是整数,浮点数,长整数等等等,返回值也可以是这些类的其中一个,排列组合一下可以有很多种组合,但是它们函数内部的功能几乎一模一样,这样的话就会比较繁琐,泛型编程就很好的解决了这一个问题。
比如算竞常用的函数 sort 可以排序,它能排很多种数据类型,只要数据类型支持小于号,那么就可以使用 sort,就算没有小于号我们也可以重载小于号使用。
函数模板123456789101112#include<iostream>#include<string>template<typename T>//古老版本中没有 typename 关键字,用的是 class,效果一样T add(T a, T b) { return a + b;}int main() { std::cout << add(1, 2) << std::endl; std::c ...
C++面向对象基础——函数与对象总结
C++面向对象基础——函数与对象总结
面向对象最后一节课了~
引入例:
12345678910111213141516class A{public: int a; void test(int num) { a += num; }};void test(A* obj, int num) { obj->a += num;}int main() { A obj; obj.test(100); test(&obj, 100);}
效率以上代码中的 A::test 函数和 test 函数实现了相同的功能。这种情况下,效率永远是类内的函数比全局函数的效率高的。这也就是为什么作用域我们会倾向于小的处理,就近原则嘛。
成员函数调用方式这里成员函数的理解就理解为整个类的就行了,它不属于一个个体。
成员函数直接调用实际上跟全局函数调用一模一样,因为在编译器就已经确定了成员函数的位置,用对象无论调用的是虚函数还是非虚函数,结果都是一致的,因为它这里认为你 ...