C++语法复习笔记-2. c++基础句法

news2024/11/25 23:51:54

文章目录

  • 1. 图灵机与三种基本结构
    • 1. 顺序结构
    • 2. 分支结构
        • 自定义结构-枚举
        • 结构体与联合体
        • 结构体数据对齐问题
    • 3. 循环结构
      • 三种循环结构
      • 反汇编查看三种结构效率
      • 实例:输出所有形如aabb的四位数的完全平方数
        • 方案1: 构造aabb数,再判断
        • 方案2:反向操作:先算出平方和,再判断是否为aabb结构
  • 2. 函数
    • 1. 总览
    • 2. 函数组成
    • 3. 指向函数的指针与返回指针的函数
    • 4. 命名空间
    • 5. 函数体调用过程
    • 6. 内联函数
        • VS设置
        • 汇编过程
  • 3. 递归
    • 1. 递归与数学归纳法
      • 基本法则
      • 递归的缺陷
      • 递归的优化
        • 循环迭代
        • 尾递归
        • 动态规划

慕课网c++课程

1. 图灵机与三种基本结构

1. 顺序结构

在这里插入图片描述

2. 分支结构

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

自定义结构-枚举

在这里插入图片描述

  • 代码示例
// demo6-2.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

#include <iostream>
using namespace std;
int main()
{
	enum wT{Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday}; // 声明wT类型
	wT weekday;
	weekday = Monday;
	weekday = Tuesday;
	//weekday = 1;             // 不能直接给int值,只能赋值成wT定义好的类型值
	cout << weekday << endl;   // 1
	//Monday = 0;             // 类型值不能做左值
	int a = Wednesday;
	cout << a << endl;        // 2

    return 0;
}

在这里插入图片描述

结构体与联合体

在这里插入图片描述

  • 示例
#include <string.h>
#include <iostream>
using namespace std;

int main()
{
	union Score 
	{
		double ds;
		char level;
	};
	struct Student
	{
		char name[6];                                 
		int age;                 
		Score s;               
	};
	cout << sizeof(Score) << endl;      // 8,取最大元素的字节作为联合体空间
	...
}

结构体数据对齐问题

  • 原则1:小于等于4字节的变量,两个变量累加的空间大于4的整数倍,就分配4的整数倍+1,反之,没有超过4的整数倍,就分配4的整数倍(例如char:1, int :4,一个4字节分配不了,就开辟两个4字节空间)
  • 原则2:大于4字节的变量,以此变量为整数进行分配,原理与以4字节为整数进行分配一致
    在这里插入图片描述
  • 内存布局的4字节的处理,即,每4字节1段,即使char,short分别占1字节和2字节,也要分配4字节
    在这里插入图片描述
  • 最大元素的整数倍的处理:最大元素内存对齐,假如int类型改为占8字节的double类型,S2要共占16字节
    在这里插入图片描述
    在这里插入图片描述
  • 调试测试
Student s1;
	strcpy_s(s1.name, "lili");
	s1.age = 16;
	s1.s.ds = 95.5;
	s1.s.level = 'A';

	cout << sizeof(Student) << endl;    // 24     18 

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 总结:
    在这里插入图片描述
// 设置成连续分配空间
#pragma pack(1)

在这里插入图片描述

3. 循环结构

三种循环结构

在这里插入图片描述

反汇编查看三种结构效率

在这里插入图片描述

  • do-while循环代码相对效率较高,只有一个跳转
// do-while语句
	sum = 0;
002A1810  mov         dword ptr [sum],0  
	index = 1;
002A1817  mov         dword ptr [index],1  
	do 
	{
		sum += index;
002A181E  mov         eax,dword ptr [sum]  
002A1821  add         eax,dword ptr [index]  
002A1824  mov         dword ptr [sum],eax  
		index += 1;
002A1827  mov         eax,dword ptr [index]  
002A182A  add         eax,1  
002A182D  mov         dword ptr [index],eax  
	} while (index <= 100);
002A1830  cmp         dword ptr [index],64h  
002A1834  jle         main+7Eh (02A181Eh)  // 比较小于0,跳回原循环体
  • while循环:两次跳转
// while语句
	int sum = 0;
002A17BE  mov         dword ptr [sum],0  
	int index = 1;
002A17C5  mov         dword ptr [index],1  
	while (index <= 100)
002A17CC  cmp         dword ptr [index],64h // 与100比较 
002A17D0  jg          main+46h (02A17E6h)   // g:大于0,就跳出循环到另个位置
	{
		sum += index;
002A17D2  mov         eax,dword ptr [sum]  
002A17D5  add         eax,dword ptr [index]  
002A17D8  mov         dword ptr [sum],eax  
		index += 1;
002A17DB  mov         eax,dword ptr [index]  
002A17DE  add         eax,1  
002A17E1  mov         dword ptr [index],eax  // 跳回到最初的位置
	}
002A17E4  jmp         main+2Ch (02A17CCh) 
  • for循环:三次跳转,相对复杂些,但代码灵活些
	// for语句
	//index = 1;
	sum = 0;
002A17E6  mov         dword ptr [sum],0  
	for (index = 1; index <= 100; ++index)
002A17ED  mov         dword ptr [index],1  
002A17F4  jmp         main+5Fh (02A17FFh)  // 跳到cmp比较操作
002A17F6  mov         eax,dword ptr [index]  
002A17F9  add         eax,1  
002A17FC  mov         dword ptr [index],eax  
002A17FF  cmp         dword ptr [index],64h  
002A1803  jg          main+70h (02A1810h) // 与while循环一样,跳出循环 
	{
		sum += index;
002A1805  mov         eax,dword ptr [sum]  
	{
		sum += index;
002A1808  add         eax,dword ptr [index]  
002A180B  mov         dword ptr [sum],eax  
	}
002A180E  jmp         main+56h (02A17F6h)  // 跳到index++操作

实例:输出所有形如aabb的四位数的完全平方数

方案1: 构造aabb数,再判断

	// aabb的完全平方数
	// 先构造aabb,再开方,判断开方后的数是否为整数,相差处理
	int n = 0;
	double m = 0;
	for (size_t a = 1; a < 10; a++) //  size_t 是一些C/C++标准在stddef.h中定义的,size_t 类型表示C中任何对象所能达到的最大长度,它是无符号整数
	{
		for (size_t b = 0; b < 10; b++)
		{
			n = a * 1100 + b * 11; //aabb
			// 难点是,开方后的数如何判断是整数:形如4.0, 5.0等
			m = sqrt(n);  
			// 方案1:相差
			if (m - int(m) < 0.00000001)
			{
				cout << n << endl;
			}
		}
	}

方案2:反向操作:先算出平方和,再判断是否为aabb结构

int high, low; // 高位aa, 地位bb
	// aabb的完全平方数
	for (size_t index = 31; ; index++) // 小于1000跳过
	{
		n = index*index;
		if (n < 1000)
			continue;   // 继续下一次循环
		if (n > 9999)
			break;        // 退出循环
		high = n / 100;   // 4567/100 = 45
		low = n % 100;   // 4567%100 = 67
		if ((high / 10 == high % 10) && (low / 10 == low % 10))   // 判断aa, bb
		{
			cout << n << endl;
		}
	}

2. 函数

1. 总览

在这里插入图片描述

2. 函数组成

在这里插入图片描述
在这里插入图片描述

3. 指向函数的指针与返回指针的函数

在这里插入图片描述

// demo6-7.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

#include <iostream>
using namespace std;
int MaxValue(int x, int y)
{
	return (x > y) ? x : y;
}
int MinValue(int x, int y)
{
	return (x < y) ? x : y;
}
int Add(int x, int y)
{
	return x+y;
}
bool ProcessNum(int x, int y, int(*p)(int a, int b))
{
	cout << p(x, y) << endl;
	return true;
}

int main()
{   
	int x = 10, y = 20;
	cout << ProcessNum(x, y, MaxValue) << endl; // 直接传递函数名称即可,指针可以指向
	cout << ProcessNum(x, y, MinValue) << endl;
	cout << ProcessNum(x, y, Add) << endl;

    return 0;
}

在这里插入图片描述

4. 命名空间

在这里插入图片描述

// stdafx.h : 标准系统包含文件的包含文件,
// 或是经常使用但不常更改的
// 特定于项目的包含文件
//

#pragma once

#include "targetver.h"

#include <stdio.h>
#include <tchar.h>



// TODO:  在此处引用程序需要的其他头文件
int test(int a);
int test(double a);
int test(int a=1, double b=2.0);

namespace quickzhao
{
	int test(int a);
}
#include "stdafx.h"
int main()
{
	int(*p)(int);
	p = test;
	int result = (*p)(1);

	result = quickzhao::test(1);

	result = test(2.0);
	result = test(1, 2.0);
    return 0;
}

5. 函数体调用过程

#include "stdafx.h"


int MaxValue(int a, int b)
{
	return (a > b) ? a : b;
}
int main()
{
	int x = 3, y = 4;
	MaxValue(x, y);
    return 0;
}


  • main函数调用过程
// main函数处理过程
int main()
{
// 初始化栈
00C01690  push        ebp      // 放进栈-寄存器-edp在栈底,esp寄存器在栈顶
00C01691  mov         ebp,esp  // 将ebb数据放进esp中
00C01693  sub         esp,0C0h // 对esp信息做了一个减法 ,这样栈顶与栈底形成一个0C0h空间
00C01699  push        ebx      
00C0169A  push        esi      // 压栈后,esp地址会继续减少,保持在栈顶
00C0169B  push        edi   
00C0169C  lea         edi,[ebp-0C0h]  
00C016A2  mov         ecx,30h  
00C016A7  mov         eax,0CCCCCCCCh  
00C016AC  rep stos    dword ptr es:[edi]  

    return 0;
00C016AE  xor         eax,eax  
}

/ 清空栈
009C16D0  pop         edi  
009C16D1  pop         esi  
009C16D2  pop         ebx  
}
009C16D3  mov         esp,ebp  
009C16D5  pop         ebp  
009C16D6  ret  
  • 自定义函数调用过程
/ 自定义函数处理过程
int MaxValue(int a, int b)
{
009C1690  push        ebp  
009C1691  mov         ebp,esp  
009C1693  sub         esp,0C4h  
009C1699  push        ebx  
009C169A  push        esi  
009C169B  push        edi  
009C169C  lea         edi,[ebp-0C4h]  
009C16A2  mov         ecx,31h  
009C16A7  mov         eax,0CCCCCCCCh  
009C16AC  rep stos    dword ptr es:[edi]  
	return (a > b) ? a : b;
009C16AE  mov         eax,dword ptr [a]  
009C16B1  cmp         eax,dword ptr [b]  
009C16B4  jle         MaxValue+31h (09C16C1h)  
009C16B6  mov         ecx,dword ptr [a]  
009C16B9  mov         dword ptr [ebp-0C4h],ecx  
009C16BF  jmp         MaxValue+3Ah (09C16CAh)  
009C16C1  mov         edx,dword ptr [b]  
009C16C4  mov         dword ptr [ebp-0C4h],edx  
009C16CA  mov         eax,dword ptr [ebp-0C4h]  
}



	int x = 3, y = 4;  // 压栈方式,从右往左
00CC166E  mov         dword ptr [x],3  
00CC1675  mov         dword ptr [y],4  
	MaxValue(x, y);
00CC167C  mov         eax,dword ptr [x]  
00CC167F  cmp         eax,dword ptr [y]  
00CC1682  jle         main+3Fh (0CC168Fh)  
00CC1684  mov         ecx,dword ptr [x]  
00CC1687  mov         dword ptr [ebp-0DCh],ecx  
00CC168D  jmp         main+48h (0CC1698h)  
00CC168F  mov         edx,dword ptr [y]  
00CC1692  mov         dword ptr [ebp-0DCh],edx  

    return 0;
00CC1698  xor         eax,eax  

6. 内联函数

  • 只处理核心逻辑,不处理堆栈,寄存器等其他处理过程,提高效率
  • 内联只是建议,不一定有效,编译器会有自己的优化
    在这里插入图片描述

VS设置

在这里插入图片描述
在这里插入图片描述

汇编过程

  • 将核心过程映射到函数调用处
	MaxValue(x, y);
00CC167C  mov         eax,dword ptr [x]  
00CC167F  cmp         eax,dword ptr [y]  
00CC1682  jle         main+3Fh (0CC168Fh)  
00CC1684  mov         ecx,dword ptr [x]  
00CC1687  mov         dword ptr [ebp-0DCh],ecx  
00CC168D  jmp         main+48h (0CC1698h)  
00CC168F  mov         edx,dword ptr [y]  
00CC1692  mov         dword ptr [ebp-0DCh],edx  

	Fib(5);
011238A8  mov         eax,5  
011238AD  test        eax,eax  
011238AF  jne         main+55h (011238B5h)  
011238B1  jmp         main+85h (011238E5h)  
011238B3  jmp         main+85h (011238E5h)  
011238B5  mov         ecx,5  
011238BA  cmp         ecx,1  
011238BD  jne         main+63h (011238C3h)  
011238BF  jmp         main+85h (011238E5h)  
011238C1  jmp         main+85h (011238E5h)  
011238C3  mov         edx,5  
011238C8  sub         edx,1  
011238CB  push        edx  
011238CC  call        Fib (0112132Ah)       // 当函数复杂时,还是call了内联函数
011238D1  add         esp,4  
011238D4  mov         eax,5  

3. 递归

1. 递归与数学归纳法

在这里插入图片描述
在这里插入图片描述

基本法则

在这里插入图片描述

递归的缺陷

在这里插入图片描述

递归的优化

循环迭代

// 循环
int Fib3(int n)
{
	if (n < 2)
	{
		return n;
	}
	int n0 = 0, n1 = 1;
	int temp; 
	for (int i = 2; i <= n; i++)
	{
		temp = n0; 	    // temp记录f(n-2)
		n0 = n1;        // n1记录f(n-1),用n0传递,是下轮的f(n-2)
		n1 = temp + n1; // n1记录这轮的f(n),是下轮的f(n-1)
	}
	return n1;
}

尾递归

  • 最后一步递归调用,之前的栈和寄存器都没有变化
// 尾递归
int Fib2(int n, int ret0,  int ret1)
{
	if (n == 0)
	{
		return ret0;
	}
	else if (n == 1)
	{
		return ret1;
	}
	return Fib2(n - 1, ret1, ret0 + ret1);
}

动态规划

int g_a[1000]; // 全局的数组,记录斐波那契数列的前1000个值
// 动态规划
int Fib4(int n)
{
	//assert(n >= 0);
	g_a[0] = 0;
	g_a[1] = 1;
	for (int i = 2; i <= n; i++)
	{
		if (g_a[i] == 0) // 用表记录斐波拉系数,没有就计算,有的话直接用
		{
			g_a[i] = g_a[i - 1] + g_a[i - 2];
		}
	}
	return g_a[n];
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/181237.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

《网络编程实战》学习笔记 Day10

系列文章目录 这是本周期内系列打卡文章的所有文章的目录 《Go 并发数据结构和算法实践》学习笔记 Day 1《Go 并发数据结构和算法实践》学习笔记 Day 2《说透芯片》学习笔记 Day 3《深入浅出计算机组成原理》学习笔记 Day 4《编程高手必学的内存知识》学习笔记 Day 5NUMA内存知…

自制DAPLink 基于ARM官方源码以及STM32F103C8T6

【本文发布于https://blog.csdn.net/Stack_/article/details/128771308&#xff0c;未经许可禁止转载&#xff0c;转载须注明出处】 一、安装工具并配置环境变量 1、python3 【官网】 【网盘】 链接&#xff1a;https://pan.baidu.com/s/1zW_H_eQlkzX3FkXuClFnTA 提取码&#…

python 操作 json 文件的种种知识点

本篇博客将带你全方位了解 Python 操作 json 文件的技术点 让你碰到 json 格式文件不在发愁 文章目录json 模块读取 JSON写入 JSON读取与写入基本用法如下json 模块进阶用法控制输出格式在 JSON 中存储 Python 特殊类型对数据进行验证和清洗第三方模块json 模块 Python 提供了…

CE自动汇编之AOB注入

目录 一、什么是AOB注入&#xff1f; 二、什么时候使用AOB注入&#xff1f; 三、代码注入 四、全部注入 五、“全部注入”和“AOB注入”的分别 六、代码注入与AOB注入的区别 CE自动汇编的模板中&#xff0c;有三种注入代码的方式&#xff1a; 第一种是代码注入&#xff…

Qt使用数据库模型中的删除详解

以下使用 QSqlTableModel 模型&#xff0c;使用tableView显示内容 以下为界面&#xff1a; 这里主要介绍删除操作&#xff1a; 删除一行为&#xff1a; int rowui->tableView->currentIndex().row();//获取行号model->revertRow(row);//删除该行model->submitAll(…

git 关于分支和仓库的理解

何时需要initgit init//初始化本地仓库.git目录如果初始化就会在当前文件夹中出现.git的目录&#xff0c;该目录默认是隐藏的&#xff0c;需要关闭显示隐藏文件才能看到。执行完git init命令后&#xff0c;当前目录就成为了工作区&#xff08;工作区可以理解为操作本地仓库的车…

MyBatis-Plus知识快速入门

文章目录1.MyBatis-Plus简介2.入门案例2.1开发环境2.2创建测试数据库和表2.3创建SpringBoot工程2.4创建实体类以及lombok的使用2.5添加mapper2.6加入日志功能3.基本的CRUD3.1BaseMapper3.2插入3.3删除3.4修改3.5查询4.通用Service4.1创建Service接口和实现类5.常用注解5.1Table…

“华为杯”研究生数学建模竞赛2005年-【华为杯】A题:城市出租车交通规划综合模型(附获奖论文和matlab代码)

赛题描述 A: Highway Traveling time Estimate and Optimal Routing Ⅰ Highway traveling time estimate is crucial to travelers. Hence, detectors are mounted on some of the US highways. For instance, detectors are mounted on every two-way six-lane highways o…

springboot 分布式全局唯一id的生成-雪花算法snowflake

一 背景描述 1.1 问题产生 在分布式系统中&#xff0c;怎么使用全局唯一id&#xff1f; 在分布式是&#xff0c;微服务的架构中&#xff0c;或者大数据分库分表中&#xff0c;多个不同节点怎么保持每台机器生成的主键id不重复&#xff0c;具有唯一性&#xff1f; 方案1&…

【算法基础】归并排序(原理、过程、例题、代码)

一、归并排序原理 1. 算法介绍 归并排序是建立在归并操作上的一种有效,稳定的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有…

力扣 2309. 兼具大小写的最好英文字母

题目 给你一个由英文字母组成的字符串 s &#xff0c;请你找出并返回 s 中的 最好 英文字母。返回的字母必须为大写形式。如果不存在满足条件的字母&#xff0c;则返回一个空字符串。 最好 英文字母的大写和小写形式必须 都 在 s 中出现。 英文字母 b 比另一个英文字母 a 更…

前端食堂技术周刊第 68 期:Astro 2.0、Nuxt v3.1.0、Bun v0.5、TS 实现 Stage 3 Decorators 提案

美味值&#xff1a;&#x1f31f;&#x1f31f;&#x1f31f;&#x1f31f;&#x1f31f; 口味&#xff1a;萝卜牛腩煲 食堂技术周刊仓库地址&#xff1a;https://github.com/Geekhyt/weekly 本期摘要 Astro 2.0Nuxt v3.1.0Bun v0.5TS 实现 Stage 3 Decorators 提案Turbore…

【算法突击】排序算法系列(一) | 程序员面试 | 冒泡排序 | 快速排序 | 归并排序

【排序算法】 冒泡排序 | 快速排序 | 归并排序 文章目录【排序算法】 冒泡排序 | 快速排序 | 归并排序1. 冒泡排序1.1 核心思想1.2 代码实现2. 快速排序2.1 核心思想2.2 时间复杂度2.2 代码实现3. 归并排序3.1 核心思想3.2 时间复杂度3.3 代码实现1. 冒泡排序 1.1 核心思想 将…

【接口自动化】接口间参数传递的一种解决方案

本文转载自&#xff1a;接口间参数传递的一种解决方案 做过接口自动化测试的同学肯定都熟悉在全链路测试过程中&#xff0c;很多业务场景的完成并非由单一接口实现&#xff0c;而是由很多接口组成的一条链路实现。例如你在淘宝上购物场景。 不同于单接口测试&#xff0c;这种链…

2 线性模型

文章目录一般流程问题引入数据集与测试集过拟合与泛化开发集监督学习和非监督学习问题分析训练集、验证集、测试集模型设计模拟训练过程课程代码课后习题代码课程来源&#xff1a; 链接文档参考&#xff1a; 链接以及 BirandaのBlog&#xff01;一般流程 对于一般的线性模型来…

微信小程序 Springboot校园招聘求职系统

基于微信小程序的校园求职系统的设计基于现有的手机&#xff0c;可以实现首页、个人中心、岗位类型管理、用户管理、企业管理、招聘信息管理、应聘信息管理、系统管理等功能。方便用户对首页、招聘信息、我的等详细的了解及统计分析 一个基本的程序包含app.json、project.confi…

谈谈SpringBoot(二)

1. Spring Boot缓存 1.1 JSR-107 Spring从3.1开始定义了org.springframework.cache.Cache 和org.springframework.cache.CacheManager接口来统一不同的缓存技术&#xff1b; 并支持使用JCache&#xff08;JSR-107&#xff09;注解简化我们开发。 Cache接口为缓存的组件规范定义…

day23|93.复原IP地址、78.子集、90.子集II

93.复原IP地址 有效 IP 地址 正好由四个整数&#xff08;每个整数位于 0 到 255 之间组成&#xff0c;且不能含有前导 0&#xff09;&#xff0c;整数之间用 . 分隔。 例如&#xff1a;"0.1.2.201" 和 "192.168.1.1" 是 有效 IP 地址&#xff0c;但是 &q…

layui框架学习(2:颜色、图标、动画)

B站教学视频中对Layui的颜色没有专门介绍&#xff0c;而Layui官方教程中虽然有颜色章节&#xff0c;但也只是简单介绍了基色调、辅色调、中性的颜色的概念及用途&#xff0c;最后说明layui 内置了七种背景色&#xff0c;以便用于各种元素中&#xff0c;如&#xff1a;徽章、分割…

Go语言基础入门第二章

Go语言环境安装 下载地址&#xff1a;https://golang.google.cn/dl/ 下载完安装包直接安装即可&#xff0c;安装完毕后&#xff0c;打开cmd控制台&#xff0c;输入”go version“查看是否安装成功以及对应安装版本。 配置环境变量Go语言需要一个安装目录&#xff0c;还需要一个…