C++入门学习笔记(一)

目录

头文件:

头文件路径包含

编译器行为

头文件保护符(监督)

命名空间

基础(声明与定义)

变量

常量

左移运算符和右移运算符

字符串:String

C风格字符串:

C++字符串:

数组

增量运算符

逻辑工具

条件判断语句

枚举

循环

while循环与do whlie循环:

for循环:

流程控制语句:


头文件:

#符号之后的都是预处理语句,会优先在实际编译发生之前处理,所以叫做预处理
//include是找到一个<>文件并将该文件的所有内容都拷贝到现在的文件内, 这些文件通常叫做头文件

#include <iostream> //input output stream 输入输出数据流头文件
#include <string> //字符串头文件

头文件路径包含

#include "Head.h"

//有些头文件使用<>有些使用""

//编译程序时有两种不同的含义,需要告诉编译器包含文件的路径是什么

//如果包含文件是在其中一个文件夹里,可以使用<>告诉编译器搜索包含路径文件夹

//而""通常用于包含相对于当前文件的文件

//例如有个log.h在cpp文件所在目录的上层目录下,可以使用../返回当前文件的上级目录 #include "../log.h"这是相对于当前文件的路径

//而<>就没有相对于当前文件的了,只需要在其中一个包含目录里面就行了

//#include "iostream"也是完全可以的

//<>只用于编译器包含路径,""引号可以做一切,通常只用它在相对路径,主要还是<>尖括号 //iostream没有包含任何后缀,它实际上是一个文件,只是没有扩展名

// (这是写C++标准库的人决定这么做的,将C++标准库与C标准库进行区分)

//C标准库通常会有.h扩展,例如:#include <stdlib.h>,但是C++文件没有

//这是一种区分C++标准库和C标准库的方法,看它们是否有.h扩展

编译器行为

//项目中的每一个cpp文件都会被编译,但头文件不会被编译,因为在预处理时包含进来了

//cpp文件被编译的时候,包含进来的文件一起被编译了,因此有了一堆将要被编译的cpp文件

//分别被编译器编译,每一个cpp文件都被编译成了一个object file(目标文件),用vs生成的文件后缀是.obj

//有了这些生成的独立的obj文件之后,就需要把这些文件合并成一个执行文件

//这就需要链接(link),它就是将所有的obj文件黏合到一起,将所有的obj文件合并成一个exe文件 //编译单独一个文件不会进行链接

//默认情况下vs会输出构建文件到debug文件夹,会有obj文件等

//当构建整个项目的时候就会进行链接,在解决方案目录下的debug文件夹下生成exe文件

//当前main函数cpp文件声明函数,其它cpp文件定义函数时

//编译器会无条件相信声明函数的存在,链接器会找到正确的函数定义在哪里(cpp文件),将函数定义导入到函数中让main调用

头文件保护符(监督)

原因:如果不小心多次包含了一个文件并转换为一个翻译单元会得到duplicate复制错误,会复制粘贴整个头文件多次
例如:当前1.h被包含在2.h,而main同时包含了1.h,2.h,相当于包含了两次1.h,会出现报错
而#pragma once的作用就是识别它是否被包含了多次,这种情况下不会报错,阻止多次包含

#pragama once
含义:监督这个头文件,阻止单个头文件多次被包含,并转换为单个翻译单元
这并不妨碍将头文件放到程序的多个位置,而只是说放在一个翻译单元一个cpp文件

#pragama once

另外一种方法

#ifndef _HEAD_H
//ifndef后面是需要检查的符号

#define _HEAD_H

#endif

//ifndef后面是需要检查的符号
//这是检查是否有一个叫做_HEAD_H的符号被定义了
//如果没有定义将继续在编译中包含后续程序代码到endif结束
//如果检查到已经被定义了,则直到endif结束,中间所有内容都不会被包含
这种头文件保护符(监督,警卫)的东西在过去被广泛使用,现在有新的更简洁的pragma once经常使用

命名空间

关键词:namespace
string,cout,cin,endl等需要用到标准命名空间

using namespace std;//std == standard 标准命名空间

基础(声明与定义)

声明 == 告诉编译器这个函数的存在(就是取名字)

定义 == 告诉编译器具体含义或者具体值,(函数体具体做了什么)(就是有什么作用)

变量

//编程的大部分内容实际上都是在使用数据,使用任何想要改变的数据,读.写.存储数据等,变量就是所操作的数据

//声明一个变量意味着为这个变量预先分配了一些内存

//变量为我们的程序提供有名字的可操作的储存空间

//变量类型决定变量大小和内存布局,以及可应用于该变量的操作集

char myCharacter; //char是character的缩写,是单个字符
初始化的含义:
这个变量没有被赋值,当声明一个变量的时候,上一个程序的内存会被保留下来,也就是说这个变量包含垃圾数据
所以需要覆盖它,给它初始化
myCharacter = 'y';
//现在它的储存空间包含了一个字符,没有多余的储存空间容纳多个字符

int myInt;
myInt = 13;
float myFloat = 7289;// 7289 = 7.289e3 //e3为10的3次方 //doube > float
// 0 0.0 0.0000都是零,计算机视其真值为false, 0.0000001真值为true, -1 ,1 真值为true

不同的初始化方式:

int a(1);
int b = 13;

常量

关键词:const
含义:
常量也就是我们熟知的阿拉伯数字之类的,其含义已经被定死了,也就是说1就是1,不能成为2
而自定义常量:也就是硬编码变量,声明并初始化为一个常量,其值不可修改,否则会编译错误

int a = 1;//这是全局变量,可以作用与所有 
//全局变量,可以直接在函数中使用 
const float PI = 3.14159;//这就是常量
//这里的PI就相当于我们定义了一个额外的数字,赋予了含义,所以其他地方不可以再修改
const float WalkSpeed = 500.f//.f代表浮点型,所以是浮点型常量 
int main(){}

左移运算符和右移运算符

左移运算符: <<
向左输出数据,从右向左执行程序
cout输出:打印输出
将字符串HelloWorld推送到cout数据流中,然后打印到终端

std::cout << "HelloWorld" << std::endl;

右移运算符: >>
向右存储数据,从左向右执行程序
cin输入:从键盘获取

std::cin >> getchar;

cin类似cout命令,cin命令是从键盘获取数据,>>代表数据流流动方向
这些运算符,叫做重载运算符,类似于函数;

字符串:String

C风格字符串:

在C语言中字符串是由\0结尾的字符数组
C语言中没有字符串类型,只有字符数组,且必须以空字符即\0结尾,以告诉程序停止在数组中查找

char hua[4] = { 'R','e','d','\0' };//此为C风格字符串,实际为字符数组
char hua[4] = { "Red" };//双引号为单引号的简写,会自动在最后放置一个空字符;

C++字符串:

关键词:String(严格意义上来说是C++的自定义类型)

//C++字符串类型,内部是拥有空字符的字符数组,这是它的工作方式

//C++中的string对象为自定义类型,结尾也有一个隐式的空字符

//C++字符串不能作为数据类型使用,必须包含C++标准库中的内容,也就是<string>头文件 //string对象是标准命名空间的一部分,所以是标准字符串或者std::string

//双引号加上包围的文本会创建一个字符串字面量,字符串字面量就是你可以赋值给字符串的值

//所以初始化字符串的内容必须是双引号

std::string str = "Red"; 
string first = "Allen"; 
string last("Jones"); 
cout << first << " " << last << std::endl;//output(Allen Jones)

string对象能够更轻松的连接字符串,用一个字符串连接另一个字符串来创建更长的字符串

string myStr = "Druid";
string& myRef = myStr;//&为引用,会改变原本的值,相当于变量的别名,本质上是一个东西
cout << myStr << endl;//输出Druid 
cout << myRef << endl;//输出Druid 
myRef += " Mechanics"; 
cout << myStr << endl;//输出Druid Mechanics 
cout << myRef << endl;//输出Druid Mechanics

数组

含义:值的容器,只能保存所有数据类型相同的值
声明:

int myIntArray[3];//声明 
myIntArray[0] = 1;//定义|初始化 
myIntArray[1] = 2; 
myIntArray[2] = 3; 
double myDubArray[] = { {3.14159},{2.71828} };//初始化

数组初始化:

int main() 
{ 
    int MyIntArray[10];//声明 
    for (int i = 0; i < 10; i++) 
    { 
        MyIntArray[i] = 1; 
        cout << MyIntArray[i] << endl; 
    } 
    //数组初始化列表: 
    int MyArray[5]={1,2,3,4,5} 
}

增量运算符

//int i = 1.5f 的情况,相当于floor,浮点型转整数型不是四舍五入而是直接丢弃小数 
int i = 1; 
i += 1;//i=2; 
i -= 1;//i=1; 
i *= 6;//i=6; 
i /= 3;//i=2; 
i %= 1;//i was 2;now i=0; 
++i;//类似于函数,input i返回i+1;前自增符 //i先加1,返回i 
i++;//返回i ,执行此行代码之后再i+1; 先返回结果后修改变量; 故称后自增符(相对于此完整的一行) 
//前自增符先计算后返回i,后自增符先返回i后计算 
i = 1; 
std::cout << ++i << std::endl; 
std::cout << i << std::endl;//返回结果都为2 
std::cout << i++ << std::endl;//返回结果为2,然后修改变量,执行下一行代码//在同一行先输出再计算
//先输出i,再计算i+1 
std::cout << i << std::endl;//返回结果为3在不同行值已经被改变 
//int j = ++i; int j = i++; //总是先执行i自身前面的内容,再返回后面的内容

逻辑工具

逻辑工具://或,与和真值表
//与:&&
//或:||
//非:   !
//等于: == (一个等于号为赋值)

if (i < k || i = k){} 
if ((i <= k && i < j) && j == ){}

条件判断语句

//尽量避免使用条件语句

//当有了条件语句所产生的分支,基本上就是在内存和分支之间跳跃(实际过程更复杂)

//检查条件,然后跳转到内存的不同的地方并从这里开始执行指令

//这意味着if语句和分支通常有比较大的开销,建议不用或少用,许多优化的代码将特意避免分支

//if-if else 由上到下依次判断,判定为真则输出并忽略以下判定
if语句:if(条件){}
if else语句:if(条件){}else{}

int x = 5; bool comparisonResult = x == 5;//这里==操作符这样运行的原因是因为它在C++标准库中被重载了 
//这里就是判断x是否等于5,返回true或者false 
//bool就像写一个函数,接受两个整数参数然后检查这两个整数的内存以确保它们是相等的,然后返回true
if(comparisonResult)//这里等同于comparisonResult == true,一般简写 
{}

特殊的else if语句: 实际上只是语法上的小技巧,并不是一个额外的独立的判断语句
else if(){}等同于
else
    if(){}
实际上是一种巧妙地隐藏语法,两个分开的语句,只是将两个语句放在了一行而已

if()
{ 
}
else 
{ 
    if()
    { 
        cout << "hello" << endl; 
    } 
}

else if不是C++的关键词,只是先else再if

switch():
//if__else if语句需要一个一个检查,导致运行缓慢
//Switch只需要检查一个条件,所以高效

int Selection = 4;
switch (Selection) 
{ 
    case 1: 
        cout << "One" << endl; 
        break; 
    case 2: 
        cout << "Two" << endl; 
        break; 
    case 3: 
        cout << "Three" << endl; 
        break; 
    case 4; 
        cout << "Four" << endl; 
        break; 
    default: 
        cout << "lnvoid choice!" << endl; 
        break; 
} //若没break,会直接进入下一个case继续执行下一个的代码

枚举

枚举是自定义数据类型
声明与定义:enum 枚举项目名{枚举项}
枚举中的项就类似于各个模式,是一个集合,每个枚举项代表一个模式,本质上还是整数
说一个例子:射击游戏中的切换主副武器就可以看成是枚举,
enum 武器模式{
主武器 = 1;
副武器 = 2;
近身武器 = 3;
}
有点像数组定义:看成是一个一行的语句,枚举中的项就类似于数组成员

以enum PlayerStatus{}为例:实际上并不是初始化或声明一个新变量,而是名为PlayerStatus的枚举类型
PlayerStatus将这些定义为选项

//定义后可以创建枚举,基本就是PlayerStatus的一个实例

//就像创建一个PlayerStatus类型状态的变量

//作为枚举变量声明类型使用

//枚举条目的本质是整型常量

//枚举项自动给定默认值,从第一项为开始,然后下一项是它的值+1

enum PlayerStatus {//定义了PlayerStatus这个枚举的项目
//PlayerStatus将这些定义为选项
PS_Crouched,
PS_Standing,
PS_Running,
PS_Sprinting
};//这是一个语句

//定义后可以创建枚举,基本就是PlayerStatus的一个实例
//就像创建一个PlayerStatus类型状态的变量
PlayerStatus status = PS_Crouched;//作为枚举变量声明类型使用
//声明一个名为status的枚举变量,值必须是定义过的枚举项之一

switch (status)//switch判断
{
  case PS_Crouched;
    cout << "Crouched" << endl;
    break;
  case PS_Standing;
    cout << "Standing" << endl;
    break;
  case PS_Running;
    cout << "Running" << endl;
    break;
  case PS_Sprinting;
    cout << "Sprinting" << endl;
    break;
    efault:
        cout<<"lnvalid chaice!"
	break;
}
//把所有东西放同一行也是可以的
enum GameState{GS_Paused,GS_Play};
//将第一个初始化为1,后面的同样默认为前面的+1;
enum ItemStatus{IS_PicvedUp = 1,IS_Drcopped,IS_Eqvipped};
//可以用不同的值初始化每个枚举常量
enum Gurrency {Copper = 1,Silver = 100,Gold = 1000};

//可以有两个常数名相同的枚举
enum PlayerStatus{PS_Crouched,PS_Standing,PS_Walking,PS_Running};
enum MovementStatus{MS_Crouched,PS_Running};

PlayerStatus status = PS_Crouched;
//区分两个常数明相同的枚举,需调用所引用枚举的名字,例:
status = PlayerStatus::PS_Running;
status = MovementStatus::PS_Running;
//status的变量类型是PlayerStatus,不接受MovementStatus类型的枚举变量

 枚举与switch,引用的例子

enum PlayerStatus
{
	PS_Running,
	PS_Walking,
	PS_Crouching
};

const float RunSpeed = 800.f;//.f代表浮点型,所以是浮点型常量
const float WalkSpeed = 500.f;
const float CrouchSpeed = 350.f;
//全局常量,可以直接在函数中使用

void UpdateMovementSpeed(PlayerStatus P_Status, float& speed);
int main()
{
	float MovementSpeed;
	PlayerStatus status = PS_Walking;//定义枚举类型的变量
	UpdateMovementSpeed(status, MovementSpeed);//&引用修改变量本身
	cout << "MovementSpeed=" << MovementSpeed << endl;//输出500.f
	system("pause");
}
void UpdateMovementSpeed(PlayerStatus P_Status, float& speed)
{
	if (P_Status == PS_Running)
	{
		speed = RunSpeed;
	}
	else if (P_Status == PS_Walking)
	{
		speed = WalkSpeed;
	}
	else if (P_Status == PS_Crouching)
	{
		speed = CrouchSpeed;
	}
}

//switch式
void UpdateMovementSpeed(PlayerStatus P_Status, float& speed)
{
	switch (P_Status)
	{
		case PS_Running:
		 speed = RunSpeed;
		 break;
		case PS_Walking:
		 speed = WalkSpeed;
		 break;
		case PS_Crouching:
		 speed = CrouchSpeed;
		  break;
	}
}

循环

while循环与do whlie循环:

whlie(条件){循环体}              先判断再循环
do{循环体}while(条件)         先循环再判断,能确保执行一次

int i = 0;
int j = 1;
while (i < j)//先判断再循环
{ i++; };//while循环,判断条件进入循环

do { i++; } //先循环再判断
while (i < j);//do while循环,确保执行一次循环;循环内需要有能够满足跳出循环的条件;否则会无限循环

for循环:

用的最多的循环了
for(条件){循环体}
条件中定义了循环方式

流程控制语句:

break 直接跳出整个循环
continue 跳过本次子循环后续内容,直接进入下一次循环
//结束此次循环,进入下一次循环重新判断条件进行循环

for (int i = 0; i < 5; i++){
	if (i % 2 == 0)
		continue;//满足条件是跳出本次循环进入下一次循环
	std::cout << "hello" << std::endl;
}

return 返回值
return 0; 会直接返回给函数,跳出函数,包括main函数

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值