控制语句主要有三个,分别为continue、break、return。他们有不同的作用。continue只能用在循环内部,他的作用简单来说就是:如果能进行下一次迭代的话直接进行下一次迭代,否则就会结束循环。break主要用在循环里面,但是它也经常出现在switch语句中,它的功能就是直接跳出循环。return可以直接完全的退出函数,如果在函数内执行到return命令就会直接完全退出函数,return是需要提供值的。
int main(){ for (int i = 0; i < 5; i++) { if (i % 2 == 0) { continue; } Log("Hello World!"); std::cout << i << std::endl; } std::cin.get(); }
得到的结果为:
你会发现当0、2、4就是为0和偶数的时候就直接跳过进入下一次循环了。
int main(){ for (int i = 0; i < 5; i++) { if (i % 2 == 0) { break; } Log("Hello World!"); std::cout << i << std::endl; } std::cin.get(); }
结果为:
你会发现什么都没有得到。也就是说当为0时执行了break,就直接把整个循环结束了。
main函数是个需要返回值的函数,你可以用return返回你想返回的任何值。
int main(){ for (int i = 0; i < 5; i++) { if ((i+1) % 2 == 0) { return 0; } Log("Hello World!"); std::cout << i << std::endl; } std::cin.get(); }
当你运行这段代码的时候,你会发现当i=1时,执行了return语句,程序就直接被关闭了,因为已经退出了main函数。还有就是return可以写在任何地方,不必写在一个循环内。
计算机和内存打交道,也就是说内存是计算机的一切,当你编写一个应用程序并启动它时,整个程序被载入内存,在你写的代码中,所有的指令告诉计算机要做什么,所有的这些都被加载到内存中,这就是你cpu如何访问你程序并执行指令的方法,当你创建一个变量时,当你从硬盘中载入数据时,所有的东西都会被存储在内存中。如果没有了内存,你将什么也做不了,而指针对管理和操作那个内存极其重要。所以什么是指针?指针就是一个整数,一个数字,它存储了一个内存地址。它和类型没有任何关系
还有一个形象的比喻就是:你把电脑的内存想象成一整块像很长的一条线。想象一条街,有一个起点,有一个终点,然后有很多房子,我们别想去马路对面的房子,对面没有!**假设有一条街,然后一整排房子,这就是内存在电脑里的样子。**它只是一个线性的、一维的线,这条街上每栋房子都有一个门牌号和地址。把这个比喻放在电脑上,把那条街上每个带地址的房子想象成一个byte,我们显然需要一种方法来给所有bytes取址,也就是我们街上所有的房子取址。因为例如有人在网上订购了一些东西,并且想要送货上门,它需要被送到正确的房子里。或者有人想要寄东西,他们把东西从他们的房子里送出去。不管怎么样,你需要能够从内存中,从那些bytes中,也就是那些房子中,读取和写入。指针就是那个地址,告诉我们房子在哪,那个特定的字节的内存在哪。
int main(){ void* ptr = 0; std::cin.get(); }
我们声明了一个void指针,这意味着,在源码中我们不关心这个数据到底是什么类型因为我们只是想存放一个地址。指针就是一个整数、一个数字,他存储了一个内存地址,他和类型没有任何关系。
int main(){ int var = 8; void* ptr = &var; std::cin.get(); }
变量前加上 & 其实是询问这个变量存放的内存地址,然后把这个地址给了ptr这个变量。
启用调试你会发现
当你吧void改为int时,启用debug
他会带我到内存中存储我的数据的地方,就是存着8这个值地址类型完全不受影响。类型只对操作内存有用,如果我想读取和写入他,内存类型可以帮助我,因为编译器会知道例如一个整数应该是4个字节,所以当我设置一个值时他会设置4个字节的内存。
现在有一个指向那个数据的指针,但是我现在想读取或者写入这块数据。例如现在这个存储8的变量,我想改变它,我该如何更改,我该如何访问他呢?这个时候dereferencing就派上用场了。我们现在是把var变成了一个指针指向var那我们如何回到var我们可以加上一个星号来实现*ptr
。这个是在解引用那个指针,也就是我现在在访问那块数据,我可以读取或者写入那块数据。如果直接加上*ptr=10
会得到一个错误信息。因为这个指针是一个void指针,计算机如何才能把一个值写到一个void指针里去?我们不知道该写入多少字节的数据。所以我们需要告诉编译器类型是什么。
int main(){ int var = 8; int* ptr = &var; *ptr = 10; std::cin.get(); }
现在当你输出var值时你会发现你得到的值为10。
也就是说你是直接访问那个地址并且改变了那个值。
以上操作都是在**stack(栈)中进行,我们也可以在heap(堆)**中创建一个变量。
int main(){ char* buffer = new char[8];//我们分配了8个字节的内存,并返回一个指向这块内存的地址的指针。 memset(buffer,0,8);//menset填充内存 接收一个指针,一个值(0),然后大小应该填充多少个字节 delete[] buffer;//因为这个变量是在堆中,所以当我们用完时需要进行删除 std::cin.get(); }
指针本身也是变量,这些指针也存储在内存中也就会有指针的指针。也就是一个变量存储着一个内存地址,它指向另一个变量,那个变量也存储着一个内存地址。
int main(){ char* buffer = new char[8]; memset(buffer,0,8); char** ptr = &buffer; delete[] buffer; std::cin.get(); }
可能会有一些遗漏的可以去看这个视频https://www.bilibili.com/video/BV1VJ411M7WR?p=16