自学内容网 自学内容网

c++笔记1

目录

结构体

关于结构体

结构体变量

成员的获取和赋值

结构体排序

结构体与模板

结构体嵌套

结构体与函数

模板与pair

模板

pair

多重循环

多重循环结构

嵌套注意事项

多重循环实例

再谈变量的作用域

多重循环的控制

嵌套中的break和continue

多重循环中的控制技巧

多重循环的break

多重循环的continue

具有相同类型的若干元素按顺序的形式组织起来,这些按序排列的同类数据元素放在一起称为数组。数组中每一个元素有唯一的下标表示。每个元素只需要一个下标就可以确定准确位置。

一维数组的声明及使用

声明数组

数组的初始化

使用数组的注意要点

数组与循环

数组的读入与遍历

读入:循环是操作数组的最好手段,我们可以利用循环逐个读入数组的值。

顺序遍历

倒序遍历

遍历元素的两两组合

数组的查找与统计

查找元素出现位置  数组经常用来存储多个数据,而保存下来的数据经常用来统计和查找,查找某个数字第一次出现的位置,可以使用以下程序:


C++的介绍:

C++是一种计算机高级程序设计语言由C语言扩展升级而产生,最早于1979年由本贾尼·斯特劳斯特卢普在AT&T贝尔工作室研发。

C++既可以进行C语言的过程化程序设计,又可以进行以抽象数据类型为特点的基于对象的程序设计,还可以进行以继承和多态为特点的面向对象的程序设计。C++擅长面向对象程序设计的同时,还可以进行基于过程的程序设计。

C++拥有计算机运行的实用性特征,同时还致力于提高大规模程序的编程质量与程序设计语言的问题描述能力。

从上述介绍中,我们可以提炼出:

- C++是对C语言的扩展升级 ----------->> C的多数特性和语法规则在C++中依然适用。

- C++是一个面向对象的程序设计语言----------->> 相对于面向方法的C语言,C++语言提出了面向对象的设计思想与 类 Class的概念

除此以外,为了方便封装各种抽象的数据类型,C++提供了功能强大的STL库,该库中有封装好的各种常用数据结构;同时,C++也提供了template类模板的方法,通过template,我们可以创造一个类模板或函数模板,再通过提供不同类型的数据,使其产生处理对应数据类型的模板类与模板函数,这样极大提高了C++代码的复用性与可移植性。

因此,可以说 C++ = C + Class + STL + Template


头文件:

#include<bits/stdc++.h>//万能头文件
#include<cstring>
#include<iostream>
#include<cstdio>
#include<iomanip>
#include<cmath>
#include<algorithm>
#include<stdlib.h>
#include<ctime>
#include<queue>
#include<vector>
#include<fstream>
#include<algorith>

计算机软件系统

1 系统软件

操作系统 各种计算机语言处理程序 支持软件 数据库管理系统

2 应用软件

程序库 软件包 套装程序 用户程序

软件系统

系统软件是指控制和协调计算金及外部设备支持应用软件开发和运行的系统

主要功能是调度,监控和维护计算机系统中各种独立的硬件,是他们可以协调工作。

系统软件是的计算机使用者和其它软件将计算机当作一个整体而不需要估计到底层每个硬件是如何工作的。桌面操作系统分为类unix和Windows

Informmation Technology 信息技术

00101100+(2)

00010101   01000001

  1. 比特:最小的储存单位。
  2. 字节:字节表示被处理的一组连续的二进制数字。通常用8位二进制数字表示一个字节,1字节=8比特。

计算机内存存储容量的单位从小到大依次是:字节。KB,MB,GB,TB;

1TB=1024GB 1GB=1024MB 1MB=1024KB 1KB=1024字节    1字节=8比特

网络

利用通信线路和设备,把分布在不同地理位置上多台计算机连接起来

发展史: 主机到终端,计算机到计算机,internet网。

功能: 资源共享,信息传输,分部处理提供系统的可靠性。

分类: 局域网、地域网、广域网。

特点分类:星型,总线,环状。树形,网状。

分层:1应用层 2表示层 3会话层 4传输层 5网络层 6数据链路层 7物理层

常见提交结果

AC accepted

答案正确

WA wrong answer

答案错误

time limit error

超时

memory limit error

内存超限

segmentation fault

数组越界

compiler error

编译错误

presentation error

表达错误,格式错误

 runtime error string

字符串检测到越界

变量,列表

定义规范: 名字里面只能有字母,数字和下划线组成。 变量名不能以数字开头

变量名中不等有空格,其他字符 变量名中不能和关键字重名   

Int的变量做除法时,结果只取整数部分

类型标识符 数组名【常量表达式】 strlen数组长度

常量表达式表示数组元素个事,可以是常量和符号常量,不是变量。

Int 数组名[常量表达式]={1 ,2 ,3 ,4 ,5 ,6}

Int 数组名[5]={1,2,3,4,5};   初始化为对应的元素值。

Int 数组名[5]={}; 所有的数组元素都初始化为0。

Int 数组名[5]={1}; 第一个元素为1,其余为0。

int 数组名[5]; 系统随机分配一个数,数值不确定。

类型名 数组名[ ][ ]

行长度可不写,列必须写。

计算机函数

48(0)65(A)97(a)

类型

字节

类型

字节

char

1

Long long

8

short

2

double

8

int

4

float

4

bool

1

从小到大可自动转换

<iomanip> cout<<fixed<<setprecision(n)<<cout<<a;

setprecision是一个计算机主函数

pow( )求幂函数  exp( )指数函数 aqat( )平方根abs( )用于求绝对值的函数。使用需要添加头文件 <cmath>

数据类型

定义标识符

占字节数

短整型

short[int]

2(16位

长整型

Long【int】

4(32位

整型

【long】int

4(32位

超长整型

Long long[int]

8(64位

无符号整型

unsigned[int]

2(16位

无符号短整型

unsigned short [int]

2(16位

无符号长整型

unsigned long[int]

4(32位

无符号超长整型

unsigned long ling

8(64位


判断循环语句

if(   ){

}else if( ){

}else{

}

运行顺序:如果括号判断为真,执行第一个大括号;如果括号判断为假,判断第二个括号判断结果:如果为真,执行第二个大括号,如果为假,执行最后一个大括号。

三目表达式(a>b)?a:b运行顺序:如果括号判断条件为真,执行问好后的语句,如果为假,执行冒号后面的语句。

while(    ){

}

注意:while的括号可以包含多个语句(中间用逗号隔开),但是只判读最后一个语句是否为真

do{

}while( );

switch(a+b){

case n:cout<<1;break;//当表达式与case值相匹配,使程序从该分支开始执行。

default:cout<<‘’; //当表达式与case值匹配,使程序从default开始执行。

}

reverse函数

·作用:将数组中某一连续的元素旋转 比如1 2 3 4 5 逆序一次得到5 4 3 2 1

·函数库函数:

· 函数使用 reverse(a,a+n)

· 说明:将a数组中从首元素到第n个元素的子数组逆序排布

· 旋转:比如数组1 2 3 4 5旋转一次得到5 1 2 3 4,再旋转得到4 5 1 2 3

continue跳过本次循环 break中断 Switch开关 default默认    case情况

for(   ;;  ){

语句

}

1.第一个冒号前的语句会首先被执行,只会执行一次。这一步允许声明并初始化任何循环控制变量。可以不在这里写任何语句,只一个分号出现。

2.接下来,会判断 condition第一个分号后)。如果为真,执行循环主体。如果为假,不执行循环主体,控制流会跳转到紧接着 for 循环的下一条语句。

3.在执行完 for 循环主体后,控制流会跳回上面的第二个冒号后的语句)。该语句允许更新循环控制变量。该语句可以留空,只要在条件后有一个分号出现即可。

4.condition再次被判断。如果为真,执行循环,这个过程会不断重复(循环主体,增加步值,重新判断条件)。在条件变为假时,for 循环终止。

十进制转二进制

int n; cin>>n;

while(n!=0){

cout<<n%2;

n/=2;

}

二进制转十进制

结构

顺序结构

语句与语句之间,框与框之间从上到下的顺序进行

选择结构

先根据条件作出判断,再决定先执行哪一种操作的算法结构

循环语句

从某处开始,按照一定条件,反复执行某一处理的算法结构

逻辑结构{集合结构,线性结构,树形结构,图形结构}

物理结构{顺序储存结构,链式储存结构}

正数的源码,反码,补码都一样。

负数的的反码,只需对符号位外各位按位 “求反”(0变1,1变0)即可。

负数的补 码是符号位为1,数值各位取反(0变1,1变0),最低位加1

逻辑符号

!逻辑非 &&逻辑与 &按位与 ||逻辑或 |按位或 逻辑表达式的结果只有两种(真) 1(假)0#非零为真 !Ture==false   !:非 !False==ture

&&有一为假结果就为假,两个都为真结果才为真。

||有一为真就为真,两个都为假结果才为假。 (2进制)1 &&1=1  1 &&0=0

有一个位是一时,结果就为一。 异或相同为零,不同为一

--i 先减1后输出 i--先输出后减1 i++先输出后加1 ++i先加1在输出

Freopen:要操作的文件名 Stdin:标准输入 Stdout:标准输出

%d    

int  

%lld  

longlong

 %c  

 char  

%s

short

%lf

double

%f

float

      非格式化原样输出 &按位与  && 逻辑与 & 取地址符  &指针

struct 结构体名    struct是关键字

成员表;       可以有多个成员

成员函数; 可以有多个也可以没有

}结构体变量表; 可以同时定义多个结构体变量用“,”隔开。

cin>>a[i].name;

Typedef struct a b;起别名

Algorithm算法

Sort(begin,end,cmp);

Begin:起始

End结束

Cmp排序规则compare

结构体

关于结构体

在 C++ 语言中,结构体 (struct) 是复合数据类型的一种。同时也是一些元素的集合,这些元素称为结构体的成员,且这些成员可以为不同的类型,成员一般用名字访问。结构体可以被声明为变量、指针或数组等,用以实现较复杂的数据结构。

注:在 C 语言中,结构体不能包含函数, C++ 中可以使用函数。

struct 结构体名{

   结构体所包含的变量或数组

 };

结构体是一种集合,它里面包含了多个变量或数组,它们的类型可以相同,也可以不同,每个这样的变量或数组都称为结构体的成员( Member )。请看下面的一个例子:

struct stu{

   string name;     //姓名  

   int num;         //学号

   int age;         //年龄

   char group;      //所在学习小组

   float score;     //成绩

};

stu 为结构体名,它包含了 5 个成员,分别是 name 、 num 、 age 、 group 、 score

结构体成员的定义方式与变量和数组的定义方式相同,只是不能初始化。

注意大括号后面的分号;不能少,这是一条完整的语句。

结构体也是一种数据类型,它由程序员自己定义,可以包含多个其他类型的数据。

像 int 、 float 、 char 等是由 C++ 语言本身提供的数据类型,不能再进行分拆,我们称之为基本数据类型;而结构体可以包含多个基本类型的数据,也可以包含其他的结构体,我们将它称为复杂数据类型或构造数据类型。

结构体变量

既然结构体是一种数据类型,那么就可以用它来定义变量。例如:

struct stu{

   string name;     //姓名  

   int num;         //学号

   int age;         //年龄

   char group;      //所在学习小组

   float score;     //成绩

};

struct stu stu1, stu2;

定义了两个变量 stu1 和 stu2 ,它们都是 stu 类型,都由 5 个成员组成。

注意在 C 语言中关键字 struct 不能少, C++ 可以省略。

这段程序里 stu 就像一个“模板”,定义出来的变量都具有相同的性质。也可以将结构体比作“图纸”,将结构体变量比作“零件”,根据同一张图纸生产出来的零件的特性都是一样的。你也可以在定义结构体的同时定义结构体变量:

struct stu{

    string name;    //姓名

    int num;        //学号

    int age;        //年龄

    char group;     //所在学习小组

    float score;    //成绩

} stu1, stu2;

将变量放在结构体定义的最后即可。

成员的获取和赋值

结构体和数组类似,也是一组数据的集合,整体使用没有太大的意义。结构体使用点号 ‘.’ 获取单个成员。获取结构体成员的一般格式为:

结构体变量名.成员名;

通过这种方式可以获取成员的值,也可以给成员赋值:

struct{

    string name;    //姓名

    int num;        //学号

    int age;        //年龄

    char group;     //所在小组

    float score;    //成绩

} stu1;

int main(){

    stu stu1;    //给结构体成员赋值

    stu1.name = "Tom";

    stu1.num = 12;

    stu1.age = 18;

    stu1.group = 'A';

    stu1.score = 136.5;    //读取结构体成员的值

printf("%s的学号是%d,年龄是%d,在%c组,今年的成绩是%.1f!\n", stu1.name, stu1.num, stu1.age, stu1.group, stu1.score);

    return 0;

}

除了可以对成员进行逐一赋值,也可以在定义时整体赋值,例如:

struct{

    string name;      //姓名

    int num;          //学号

    int age;          //年龄

    char group;       //所在小组

    float score;      //成绩

}

stu1, stu2 = { "Tom", 12, 18, 'A', 136.5 };

结构体排序

C++ 标准库提供的 sort ,不仅可以对 int,double... 等系统类型进行排序,同样可以对结构体排序。

只要按照标准书写 cmp 函数即可,下面来看一个例子:

struct node{

   int a;

   int b;

   double c;

}

有一个 node 类型的数组 node arr[100] ,想对它进行排序:先按 a 值升序排列,如果 a 值相同,再按 b 值降序排列,如果 b 还相同,就按 c 降序排列。就可以写这样一个比较函数:

bool cmp(node x,node y){

    if(x.a != y.a) return x.a < y.a;

    if(x.b != y.b) return x.b > y.b;

    return x.c > y.c;

}

使用 C++ 标准库的 sort ​,我们可以轻松定义两个相同类型元素的大小。在之前排序的课程中,曾经讲到过稳定排序这个概念,当一个数列中有相同的元素时,排序后这些相同元素之间的顺序可能会同初始序列不一样。使用非稳定的排序方法对一个整型数组排序,对于普通的一个数字 5 ,如果数组中同时存在多个 5 ,我们无法区分每个 5 究竟是来自于最初数组中的那个位置。标准库中的 sort  是使用快速排序实现的,快速排序是一种非稳定排序,如果我们的比较函数只比较结构体的某一个值,则原有的顺序可能会被打乱,这点在我们写代码的时候要特别注意,有可能因为顺序问题造成计算结果的错误。那么如何能够使用 sort的同时,又保证排序后的数组顺序仍然是稳定的呢?需要做特殊的处理,可以在结构体中增加一个属性,专门用来记录在原始数组中的位置,在其它值相等的情况下,再比较这个位置数据,这相当于没有两个值是完全相等的,这种情况下稳定排序的结果与非稳定排序是相同的。

结构体与模板

结构体嵌套

在结构体中我们可以定义自己需要的成员及成员类型。成员类型可以是 C++ 的标准类型,也可以是另一个结构体。例如:

struct Book{

    int book_id;

    string name;

    string ISBN;

};

struct Home{

    int size;

    Book One;

};

需要注意的是,这个类型不可以是自己。例如:

struct Book{

    int book_id;

    string name;

    string ISBN;

    Book book;

};

这个程序无法通过编译。

结构体与函数

结构体与其他类型相同,可以作为函数的参数进行传递。

将结构体作为函数参数时,遵循值传递的规则。函数体内对结构体进行修改并不会影响原来变量的值。

 struct Book{

    int book_id;

    string name;

};

void setBook(Book bk){

    bk.book_id = 3;

    bk.name = "World";

}

int main(){

    Book s;

    s.book_id = 1;

    s.name = "Hello";

    setBook(s);

    cout << s.book_id << endl;

    cout << s.name << endl;

}

运行结果如下: 1 Hello

可以看到把结构体变量 s 作为函数的参数传入,并在函数内部对传入的 s 的内容做修改,是不会影响到原来 s变量的取值的。如果希望能够在调用函数的内部,修改传入参数的值,则需要增加引用传递符号 & 。或者把函数的返回值类型设为结构体。

struct Book{

    int book_id;

    string name;

};

void setBook(Book &bk){

    bk.book_id = 3;

    bk.name = "World";

}

int main(){

    Book s;

    s.book_id = 1;

    s.name = "Hello";

    setBook(s);

    cout << s.book_id << endl;

    cout << s.name << endl;

}

运行结果如下: 3 World

结构体除了可以作为函数的参数,也可以作为函数的返回值。

struct Books {

   int Id;

   string Title;

} book;

void F1(Books n){

    n.Id += 8;

    n.Title += " Ok";

}

void F2(Books &n){

    n.Id += 8;

    n.Title += " Ok";

}

Books F3(Books n){

    n.Id += 8;

    n.Title += " Ok";

    return n;

}

int main() {

    Books a, b;

    a.Id = 3;

    a.Title = "CL1";

    b = a;

    F1(a);

    cout << a.Id << " " << a.Title << endl;

    F2(a);

    cout << a.Id << " " << a.Title << endl;

    a = F3(b);

    cout << a.Id << " " << a.Title << endl;

    return 0;

}

这段程序输出的结果如下:3 CL111 CL1 Ok11 CL1 Ok

第一个函数 F1(n) 中虽然对传入参数进行了修改,但并不影响原来 a 的值。

第二个函数 F2(n) 使用了 & 符号传递参数,在函数中修改传入参数,影响了原来 a ​ 的取值。

第三个函数 F3(n) ,我们将返回值重新赋值给 a , 影响了 a 的取值。如果把 a 作为函数的参数,传入函数并执行时,在函数内部对传入的 a 的内容做修改,是不会影响到原来 a 变量的取值的。如果希望能够在调用函数的内部,修改传入参数的值,则需要增加引用传递符号 & 。或者把函数的返回值类型设为结构体。

模板与pair

模板

我们先来想一下这个问题:在使用数组时,数组的类型可以是 int,double  ... 甚至我们自己定义的结构体。这些数组都需要有添加,删除,甚至排序功能。而函数的参数类型是确定的,如果形参是 int 则不能处理 double 类型的数据。因此对于每一种类型,我们都需要写一遍对应的程序。那么能不能某个函数只写一次,就可以套用在各种类型上呢?答案是:可以。你需要使用模板编程。模板是泛型编程的基础, C++ 中的库容器、迭代器和算法,都是泛型编程的例子,它们都使用了模板的概念。完全理解模板,涉及的知识较广,所以我们不展开介绍,仅仅告诉大家什么是模板,如何使用模板,以及模板存在的意义。

pair

pair 是 C++ 标准库提供的模板类,它可以将 2 个数据组合成一组数据。它包括了 2 个成员变量 first 和 second 。但这两个成员的类型却是通过模板来来声明的。我们使用自定义的结构体也可以完成同样的功能

//创建一个空的pair对象(使用默认构造),它的两个元素分别是T1和T2类型,采用值初始化。

pair<T1, T2> p1;

我们来看一个例子:

pair<int, string> p1;

pair 的后面跟了两个类型,类似于定义了这样一个结构体:

struct myPair{

    int first;

    string second;

};

myPair p1;

这个结构体有 2 个成员 first 和 second 。他们的类型分别是 int 和 string 。

与 pair 有关常用的函数及使用:

//创建一个空的pair对象(使用默认构造),它的两个元素分别是T1和T2类型,采用值初始化。

pair<T1, T2> p1;

//创建一个pair对象,它的两个元素分别是T1和T2类型,其中first成员初始化为v1,second成员初始化为v2。

pair<T1, T2> p1(v1, v2);

// 以v1和v2的值创建一个新的pair对象,其元素类型分别是v1和v2的类型。

make_pair(v1, v2);

结构体不能嵌套自己,但是 pair 是可以嵌套的,例如:

void setBook(pair<int, pair<int, string> > &s){

    s.first = 3;

    s.second.first = 4;

    s.second.second = "World";

}

int main(){    //s的first类型是int,second类型是pair<int, string>

    pair<int, pair<int, string> > s;  

    s.first = 1;    //创建一个pair<int, string>赋值给 s的second成员

    s.second = make_pair(2, "Hello");

    setBook(s);

    cout << s.first << endl;

    cout << s.second.first << endl;

    cout << s.second.second << endl;

}

pair 的嵌套其实与之前所说的结构体嵌套情况有所不同,结构体不能嵌套自己,是因为某个值类型的数据类型中不能包括自己本身。而上面 pair ​ 的例子可以嵌套是因为 pair<int,pair<int,string>>与 pair<int,string>并不是相同的数据类型,因此不存在自己包含自己的情况。

函数(方法)

typeName functionName(list){

代码;

return value;

}

//list:函数的参数

name和value的类型一样。

参数的传递

函数分为:

形参:定义函数时的参数 实参:调用函数时的参数

函数在调用时,实参的值对应传递给形参。

数组 (int a[],int n);

多重循环

多重循环结构

一个循环体语句中又包含另一个循环语句,称为循环嵌套。我们都知道循环结构是重复做某一件事情,那么我们重复做的这件事中如果恰好也包含循环结构,会发生什么事情呢?

我们观察下面这段代码:

for (int i = 1; i <= n; i++) {       //外层循环

    for (int j = i; j <= m; j++) {   //内层循环

        cout << i << " " << j << endl;    }

}

我们都知道,循环中大括号里是循环体,也就是我们要做的事情,这件事情我们要做 n 次(因为循环是 1−>n )的。那么我们假设现在 i=1 ,我们来具体看一下这件事情都做了什么。这件事情也是由一层循环组成,循环从 i(1)−>m 进行,按照语句执行应当顺次输出:

1 1

1 2

1 3

...

1 m

这个时候内层循环做完一遍,回到外层循环,外层循环开始进入下一步, i 由 1 变为 2 ,这一次内层循环从 i(2)−>m 进行,顺次输出。

2 2

2 3

2 4

...

2 m

这就是循环嵌套执行的过程。

嵌套注意事项

使用循环嵌套时,内层循环和外层循环的循环控制变量不能相同。

循环嵌套结构的书写,最好采用“右缩进”格式,以体现循环层次的关系。

尽量避免太多和太深的循环嵌套结构循环嵌套可以帮助我们解决很多问题,在 C++ 语言中经常被用于按行列方式输出数据。

多重循环实例

多重循环并不限制循环语句的使用,可以两重循环都是 for 循环,也可以 for 和 while 混用。

for(int i = 0; i < 10; i++){

    for(int j = 0; j <= i; j++)    {

        cout << i * j << endl;

    }

}

for(int a = 0; a < 10; a++){

    int b = 10;   

    while(b > 0)    {

        cout << a + b << endl;

        b--;

    }    

}

int b = 10;

while(b > 0){

    for(int a = 0; a < 10; a++)    {

        cout << a + b << endl;

    }    

        int c = 0;

        while(c < b)    {

        cout << c + b << endl;

        c++;

    }  

   b--;

}

以上这几种循环方法,都是没有问题的。

我们还可以通过外层循环的变量,控制内层循环的循环次数。

for(int a = 10; a <= 100; a+=2){

    for(int b = 0; b < a; b++)    {

        cout << "*";

    }

    cout << endl;

}

**********************

......

上面这段程序,第一行会输出 10 ​ 个 连在一起的 ∗ ​,因为内部循环的 cout ​ 部分,没有输出任何空格或换行。并且在第一次循环时 a=10 ​,因此内部循环会被执行 10 ​ 次。这之后,会输出一个换行,因为在外部循环的后面,有一句话专门输出换行: cout<<endl; ​。

再谈变量的作用域

在之前的学习中,我们已经讲过变量的作用域,以及局部变量和全局变量。即使是局部变量,仍然存在自己的作用域,我们先来看一段循环的程序。

for (int i = 1; i <= n; i++) {       //外层循环

    for (int j = i; j <= m; j++) {   //内层循环

        int k = i + j;

        cout << i << " " << j << " " << k << endl;

    }

    cout << j;

}

上面这段程序会出现编译错误,并且会告诉你 cout<<j 这句话中的 j 没有声明。而我们在之前的代码中,已经明确写明了 int j=i; ( for 循环中)。为何会出现没有声明的错误呢?这是因为 for 循环中 j 的作用域只限于这个内层循环当中,即 for 语句以及 {} 所包裹的部分。所以在循环之外,再次调用 cout<<j 时,已经超出了变量的作用域,会出现编译错误。

同样的道理,循环体中声明的变量 k ,作用域也仅限于内层循环。

for (int i = 1; i <= 50; i++) {       //外层循环

    int k = i;

    for (int j = i; j <= 50; j++) {   //内层循环

        int k = i + j;

        cout << i << " " << j << " " << k << endl;

    }

        cout << k << endl;

}

而这段程序,却可以正常编译通过。我们看到变量 k 被声明了两次,却不会报错。这是因为内层循环中的变量 k 覆盖了外层循环的变量 k ,这与局部变量覆盖全局变量类似。尽管程序可以执行,但我们不建议大家这样使用变量,会让程序的可读性下降,也是为自己挖坑。

与上面情况类似的,还有这种代码:

for (int i = 1; i <= 50; i++) {       //外层循环

    for (int j = i; j <= 50; j++) {   //内层循环

        int k = i + j;

        cout << i << " " << j << " " << k << endl;

    }

    for (int j = i * 2; j <= 50; j++) {   //内层循环

        int k = i + j;

        cout << i << " " << j << " " << k << endl;

    }

}

这段代码也是可以正常编译执行的,其中两个内层循环的 j,k 各自有自己的作用域,互不影响干涉。

变量作用域的问题不限于循环结构, 选择结构中也存在。

int i;

cin >> i;

 if(i < 10){

    int v = 100;

    cout << v << endl;

}else{

    int v = 80;

    cout << v << endl;

}

在这段程序中, int v=100 中 v 的作用域仅限于上下两个 {} 之间( if 后面的一对)。 int v=80 中 v 的作用域仅限于他的上下两个 {} 之间( else ​ 后面的一对)。

多重循环的控制

多重循环结构是之后的学习中经常会遇见的结构,如同在循环结构那章时所讲的。计算机的优势是在于运算速度,在不考虑程序代码的运行效率时,解决问题如果不使用循环结构,那么写代码所需要的时间可能并不比手工运算的耗时优越太多。

在学习多重循环结构中,我们可能会遇见的难点主要有:

内外层循环的执行顺序:当有内、外两层循环时,每一次进入外层循环,都会完整执行一遍内层循环,即执行到不满足内层循环的条件才停止。

循环变量的作用域:主要的疑惑点应该是 for 循环语句的控制变量,比如 for(int i=0;i<n;i++) ,如果变量 i 是在 for 语句的第一个表达式中声明的,那么 i 的作用域就是被 for 循环所控制的语句,即 for 语句之后第一个花括号或分号,脱离这个作用域变量 i ​ 就会失效。

嵌套中的break和continue

内层循环的 break ,只会让程序跳出当前的内层循环,继续外层的循环。

int main() {

    for(int i = 2; i < 100; i++)    {

        bool flag = false;

        for(int j = 2; j * j <= i; j++)        {

            if(i % j == 0)            {

                flag = true; //标识为合数并推出

                break;

            }

        }

        if(!flag)

            cout << i << " ";

    }

    return 0;

}

2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97

这段程序将会输出 100 以内的质数。

程序流程如下:

st=>start: int i = 2

op1=>operation: int j = 2

op2=>operation: 标识为合数

op3=>operation: j = j + 1

op4=>operation: i = i + 1

op5=>operation: 退出内层循环

op6=>operation: 标识为素数

op7=>operation: 输出质数i

condi=>condition: 如果i < 100

condj=>condition: 如果j * j < i

condbreak=>condition: 如果i是j的倍数

condout=>condition: 判断标识

e=>end: 结束

st->condicondi(yes)->op6->op1->condjcondi(no)->econdj(yes)->condbreakcondj(no)->op5condbreak(yes)->op2->op5

op5->condoutcondbreak(no)->op3->condjcondout(yes)->op7->op4condout(no)->op4->condi

如果循环层数大于 2 时, break 每次只会跳出当前循环,继续执行上一层循环的程序。

continue 则是跳过当前循环后面的程序,继续当前这一层的循环。

int main() {

    for(int i = 0; i < 50; i++)    {

        if(i % 7 == 0)

            continue;    

        int t = i;

        bool flag = false;      

        while(t > 0)        {

             if(t % 10 == 7)            {

                flag = true;

                break;

            }

            t /= 10;

        }    

        if(!flag)

            cout << i << " ";

    }

    return 0;

}

1 2 3 4 5 6 8 9 10 11 12 13 15 16 18 19 20 22 23 24 25 26 29 30 31 32 33 34 36 38 39 40 41 43 44 45 46 48

上面的程序将会输出 50 以内,与 7 无关的数,数字中不包括 7 并且不是 7 的倍数。

程序中如果 i 是 7 的倍数,则直接 continue ​ ,不用做逐个数位的判断。

多重循环中的控制技巧

多重循环的break

我们有时会利用多重循环来找到符合某些条件的答案,在执行这种循环时,往往是找到了某个答案就要输出答案并退出最外层的循环。但我们知道 break 只能退出当前循环,如何处理退出多重的情况呢?

编程中最常用的方法是通过函数来解决,但这部分知识目前还没有讲到,如何利用现有知识解决这个问题呢?

需要利用一些标识变量,通过这个变量的取值,来判断是否已经找到了答案,如果找到了则在每一层都执行相应的 break 。

bool flag = false;

for(int i = 0; i < n; i++) {

    for(int j = 0; j < i; j++) {

        if(找到了) {

            flag = true;

            break;

        }

    }

    if(flag)

        break;

}

多重循环的continue

多重循环中的 continue 只能解决当前循环的继续执行,这点同 break 相同,如果希望控制更外层的循环执行 continue,也需要利用标识变量,通过这个变量的取值来控制每一层循环应当如何处理。


一维数组

具有相同类型的若干元素按顺序的形式组织起来,这些按序排列的同类数据元素放在一起称为数组。数组中每一个元素有唯一的下标表示。每个元素只需要一个下标就可以确定准确位置。

一维数组的声明及使用

声明数组

在 C++ 语言当中, 数组定义的格式是这样规定的:

数据类型 数组名[数组大小]

数组大小表示数组元素的个数。是一个 >=0 的整数。

int months[12];  //声明了一个名为months的数组, 这个数组有12个int型元素, 编译器会在内存中开辟一段连续的存储单元。

int n = 12;

int months[n];//这种声明方式,在低版本的C++语言里可能会报错

在 C++ 语言中,数组的编号从 0 开始,即 months[12] 数组中第一个元素是 months[0], 最后一个元素是 months[11], 这样通过下标访问数组中单个的元素,就和我们之前熟悉的变量一样使用了。

int a[3] = {1, 2, 3};

如果数组没有进行初始化,那么数组内的元素将是不确定的,是以前遗留在改内存单元中的值。初始化时,初始化的元素可以少于数组大小,编译器将其他元素设置成 0 。

int a[4] = {1, 2, 3};

那么 a[0] = 1, a[1] = 2, a[2] = 3, a[3] = 0

如果方括号内不填写数组大小, 编译器将自动计算初始化的元素并设置为数组大小。

int a[] = {5, 3, 1};   //a数组的大小为3.

使用数组的注意要点

同一个数组, 所有元素的数据类型都相同。由于编译器不做下标的越界检查, 所以必须要注意下标的越界问题, 避免下标越界这样的错误发生。数组不能直接进行赋值操作, 只有数组中的元素可以进行赋值操作, “ int a[5], b[5]; ”是无法使用” b = a;  ”进行赋值的

数组与循环

数组的读入与遍历

读入循环是操作数组的最好手段,我们可以利用循环逐个读入数组的值。

int a[10000];  //定义一个元素个数为10000的数组

int main() {

    int n;

    cin >> n;

for (int i = 0; i < n; i++)    //输入

        cin >> a[i];

    return 0

}

这段程序会让你先输入一个数 n ,表示数组元素的数量,再输入 n 个数,程序会将这 n 个数保存在数组 a 中。

顺序遍历

使用循环,还可以方便的遍历数组,方便我们进行数据的处理。

int a[10000];  //定义一个元素个数为10000的数组

int main() {

int n;

    cin >> n;

    for (int i = 0; i < n; i++)    //输入

        cin >> a[i];

    for (int i = 0; i < n; i++)    //输出

        if(a[i] % 2 == 0)

            cout << a[i] << endl;

    return 0;}

以上程序将会读入 n 个数,然后顺序遍历输出其中所有的偶数。

倒序遍历

除了顺序遍历,数组还可以倒序遍历。

int a[10000];  //定义一个元素个数为10000的数组

int main() {

int n;

    cin >> n;

    for (int i = 0; i < n; i++)    //输入

        cin >> a[i];

    for (int i = n - 1; i >= 0; i--)    //输出

        if(a[i] < 0)

            cout << a[i] << endl;

    return 0;

}

以上程序将会读入 n 个数,然后倒序输出其中所有的负数。

遍历元素的两两组合

有时候我们会利用程序遍历元素的两两组合,这时我们需要利用双重循环。

int a[10000];  //定义一个元素个数为10000的数组

int main() {

    int n;

    cin >> n;

    for (int i = 0; i < n; i++)    //输入

        cin >> a[i];

    for (int i = 0; i < n; i++) {

        for(int j = i + 1; j < n; j++)

            cout << a[i] * a[j] << endl;

    }

    return 0;

}

数组的查找与统计

查找元素出现位置  数组经常用来存储多个数据,而保存下来的数据经常用来统计和查找,查找某个数字第一次出现的位置,可以使用以下程序:

int a[10000];  //定义一个元素个数为10000的数组

int main() {

int n, v;

    cin >> n;

    for (int i = 0; i < n; i++)    //输入

        cin >> a[i];

    cin >> v; //要查找的数据

    for (int i = 0; i < n; i++) {

        if(a[i] == v) {

            cout << i << endl;

            break;

        }    }

    return 0;}

查找某个数字最后一次出现的位置,可以使用以下程序:

int a[10000];  //定义一个元素个数为10000的数组

int main() {

    int n, v;

    cin >> n;

    for (int i = 0; i < n; i++)    //输入

        cin >> a[i];

    cin >> v; //要查找的数据

    for (int i = n - 1; i >= 0; i--) {

        if(a[i] == v) {

            cout << i << endl;

            break;

        }}

    return 0;

}

统计元素数量

统计某个数字出现的次数,可以使用以下程序:

int a[10000];  //定义一个元素个数为10000的数组

int main() {

    int n, v, cnt;

    cin >> n;

    for (int i = 0; i < n; i++)    //输入

        cin >> a[i];

    cin >> v; //要查找的数据

    for (int i = 0; i < n; i++) {

        if(a[i] == v)

            cnt++;

    }

    cout << cnt << endl;

    return 0;

}

统计大于某个数字的数有多少个,可以使用以下程序:

int a[10000];  //定义一个元素个数为10000的数组

int main() {

    int n, v, cnt;    cin >> n;

    for (int i = 0; i < n; i++)    //输入

        cin >> a[i];

    cin >> v; //要查找的数据

    for (int i = 0; i < n; i++) {

        if(a[i] > v)

            cnt++;

    }

    cout << cnt << endl;

    return 0;

}

记录数组中的最值可以使用以下程序统计数组中最大的数。

int a[10000];  //定义一个元素个数为10000的数组

int main() {

    int n, max;    cin >> n;

    for (int i = 0; i < n; i++)           cin >> a[i];

    for (int i = 0; i < n; i++) {

        if(a[i] > max)

            max = a[i];

    }

    cout << max << endl;


原文地址:https://blog.csdn.net/weixin_70468627/article/details/135965647

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!