CSP初赛复习-13-C++语言基础-进阶
变量
变量代表内存中具有特定属性的一个存储单元。它是一个地址和一个值的统称
地址
C语言地址,是指内存地址的概念。计算机内存中的各个存储单元都是有序的,按字节编码
每个字节有一个唯一的编码
变量地址
获取变量地址,使用&
示例
#include <iostream>
using namespace std;
int main(){
int a=5;
cout<<&a<<endl;
float b=4.15;
cout<<&b;
}
/*
输出结果
0x70fe1c
0x70fe18
*/
数组变量地址
数组中的变量是相同类型
数组中的变量按顺序存储,数组中的变量和地址就有了相应的对应关系
比如:
int a[5]={1,2,3,4,5};

&a[0]=0x70fe00则 &a[1]=0x70fe04
因为a是整形,a[0]占4个字节,对应占用4个地址
示例
#include <iostream>
using namespace std;
int main(){
//a数组是int类型,数组中每个元素占4个字节
//数组顺序存储,&a[1]=&a[0]+4; &a[0]=0x70fe00则 &a[1]=0x70fe04
int a[5]={1,2,3,4,5};
for(int i=0;i<5;i++){
cout<<&a[i]<<endl;
}
}
/*
输出结果
0x70fe00
0x70fe04
0x70fe08
0x70fe0c
0x70fe10
*/
指针与数组
1 数组名是数组首元素的地址
#include <iostream>
using namespace std;
int main(){
int a[5]={1,2,3,4,5};
cout<<&a<<endl;
cout<<&a[0];//这2个地址相同
}
/*
输出结果
0x70fe00
0x70fe00
*/
2 地址运算
地址+1,相当于+本数据类型的字节数
比如 int类型,+1相当于+4
#include <iostream>
using namespace std;
int main(){
int a[5]={1,2,3,4,5};
cout<<&a<<endl;//0x70fe00
cout<<a+1<<endl;//0x70fe04 -int类型变量,占4个字节,所以地址变量+1,实际+4
long long b[5]={1,2,3,4,5};
cout<<&b<<endl;//0x70fdd0
cout<<b+1<<endl;//0x70fdd8 -long long类型变量,占8个字节,所以地址变量+1,实际+8
}
/*
输出结果
0x70fe00
0x70fe04
0x70fdd0
0x70fdd8
*/
3 指针数组
1 使用指针访问数组元素
通过改变指针遍历的地址,遍历地址对应的数组元素
#include <iostream>
using namespace std;
int main(){
int a[5]={1,3,5,7,9};
int *p;//声明指针变量 p
p=a;//把a数组首元素地址赋值给指针p
cout<<p<<" "<<*p<<endl;//输出指针p对应地址的值
cout<<p+1<<" "<<*(p+1);//输出指针p对应地址下一个元素地址的值
}
/*
输出结果
0x70fdf0 1
0x70fdf4 3
*/
2 使用指针遍历数组
通过指针遍历数组元素地址的值
#include <iostream>
using namespace std;
int main(){
int a[5]={1,3,5,7,9};
int *p;//声明指针变量 p
p=a;//把a数组首元素地址赋值给指针p
for(int i=0;i<5;i++){
cout<<*(p+i)<<endl;//根据首地址每次加1 2 3 对应地址加4 8 12
}
}
/*
输出结果
1
3
5
7
9
*/
3 指针数组
声明指针数组int (*p)[5]; 指向对应数组中对应元素的地址
#include <iostream>
using namespace std;
int main(){
int a[5]={1,3,5,7,9};
int (*p)[5];//声明指针数组p 里面包括5个指针变量
p=&a;//把a数组赋值指针数组
for(int i=0;i<5;i++){
cout<<(*p)[i]<<endl;//取出对应指针数组地址的值
}
}
/*
输出结果
1
3
5
7
9
*/
4 指针访问二维数组
指向元素的指针,指向二维数组首地址
int a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};
int *p=&a[0][0];
使用指针遍历二维数组
#include <iostream>
using namespace std;
int main(){
int a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};
int *p=&a[0][0];
for(int i=0;i<3;i++){
for(int j=0;j<4;j++){
printf("%2d ",*(p+i*4+j));
}
printf("\n");
}
}
/*
输出结果
1 2 3 4
5 6 7 8
9 10 11 12
*/
使用指针数组遍历二维数组
#include <stdio.h>
int main(){
int a[3][4]={0,1,2,3,4,5,6,7,8,9,10,11};
int(*p)[4];//指针数组临时变量 表示一行
int i,j;
p=a;
for(i=0; i<3; i++){
//*(p+i)取出每行的首地址
//*(p+i)+j 每行在首地址基础上到第几列
for(j=0; j<4; j++) printf("%2d ",*(*(p+i)+j));
printf("\n");
}
return 0;
}
/*
输出结果
0 1 2 3
4 5 6 7
8 9 10 11
*/
函数
C++ 中的函数由一段相对独立的代码组成,这段代码能实现某一项具体、独立、完整的功能
函数在程序设计中的作用主要有两个,一是“代码重用”;二是“问题分解”
1 函数的定义
数据类型 函数名(形式参数表)
{
//函数体执行语句
...
}
int max2(int x, int y)
{
//函数体执行语句
return (x > y) ? x : y;
}
2 函数的调用
函数名(实参列表)
max2(5,9);
3 示例
#include<iostream>
using namespace std;
int max2(int x, int y){
return (x > y) ? x : y;
}
int main(){
int a = max2(10, -1);
cout<<a<<endl;
return 0;
}
/*
输出结果
10
*/
指针与函数
1 函数内部指针变量指向地址交换,对main函数变量无影响
#include<stdio.h>
void fun( int *a, int *b ){
int *k;//临时指针变量
//交换函数局部变量a b对应地址 对fun函数外无影响
k = a; a = b; b = k;
}
int main(){
int a = 3, b = 6, *x = &a, *y = &b;
fun( x, y );
printf( "%d,%d ", a, b );
}
/*
输出结果
3,6
*/
2 传地址和传指针都可以
#include <stdio.h>
void fun( int *a, int *b ){
int *k;
//交换函数局部变量a b对应地址 对fun函数外无影响
k = a; a = b; b = k;
}
main(){
int a = 3, b = 6, *x = &a, *y = &b;
fun( x, y );//可以传指针 指针指向地址
printf( "No.1: %d,%d ", a, b );
fun( &a, &b );//可以传地址 传地址和传指针效果一样
printf( "No.2: %d,%d\n", a, b );
}
/*
输出结果
No.1: 3,6 No.2: 3,6
*/
3 通过指针交换变量的值
#include <stdio.h>
void fun(int* px, int* py) {
int tmp = 0;
//交换指针指向变量的值 即 交换里main函数 num1 num2的值
tmp = *px;
*px = *py;
*py = tmp;
}
int main(){
int num1 = 1;
int num2 = 2;
fun(&num1, &num2);
printf("num1 = %d num2 = %d\n", num1, num2);
return 0;
}
/*
输出结果
num1 = 2 num2 = 1
*/
引用的概念
引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空间,
它和它引用的变量共用同一块内存空间
1 修改引用变量 变量都修改
#include <iostream>
using namespace std;
int main(){
int a=10;
int& b=a;//给变量a起一个别名 叫b
cout<<"a= "<<a<<endl;
cout<<"b= "<<b<<endl;
b=20;//修改了b 则a和b都修改了
cout<<"a= "<<a<<endl;
cout<<"b= "<<b<<endl;
return 0;
}
/*
输出结果
a= 10
b= 10
a= 20
b= 20
*/
2 引用做函数参数 -外部变量也被修改
#include <iostream>
using namespace std;
void fun(int & a, int & b){
int t;
t = a;
a = b;
b = t;
}
int main(){
int a=3,b=5;
fun(a,b);//引用是同一个 直接交换了a b的值
cout<<"a="<<a<<" b= "<<b;
return 0;
}
/*
输出结果
a=5 b= 3
*/
递归函数
递归是返回调用自身函数,一个函数在它的函数体内调用它自身称为递归调用
每次把问题范围缩小,直到范围缩小到可以直接得到边界数据的结果,
然后根据已计算的结果再返回路上求出对应的解
1 递归重要概念
递归式-递归函数
将原问题分为若干规模较小、相互独立、与原问题形式相同或相似的子问题
比如:斐波那契数列

由上可知递归式为:F(1)=1,F(2)=1, F(n)=F(n - 1)+F(n - 2)
递归边界
递归边界则是分解的尽头,如果递归式不断递归而不进行阻止,那么最后将进入无穷尽的死循环,将无法解
决问题
2 经典示例
问题1
使用递归求解n的阶乘
分析
n!= 123…n
n!= (n-1)!*n
于是就把规模为n的问题转化为求解规模为n-1的问题了

由上可知:每一项是上一项结果*当前项
递归式为:F(n) = F(n-1)*n
递归边界:
由于 0!=1 因此不妨以F(0)=1作为递归边界
示例代码

执行过程

问题2
求斐波那契数列的第n项
分析
F(n)=F(n - 1)+F(n - 2)
把规模为n的问题转化为求解规模为n-1和n-2和

由上可知:从第三项开始,当前项为前两项之和
递归式为: F(n)=F(n - 1)+F(n - 2)
递归边界:
由于从第三项开始,当前项为前两项之和,因此F(1)=1和F(2)=1作为递归边界
示例代码

执行过程

CSP初赛复习-13-C++语言基础-练习题
https://www.cnblogs.com/myeln/articles/17564414.html
作者:newcode 更多资源请关注纽扣编程微信公众号

从事机器人比赛、机器人等级考试、少儿scratch编程、信息学奥赛等研究学习

浙公网安备 33010602011771号