C/C++教程

【C++】大纲及疑惑点二

本文主要是介绍【C++】大纲及疑惑点二,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

目录

    • 程序控制结构
      • 预处理命令
      • 语句
      • C++的9种控制语句
    • 数组
    • 函数
      • 函数的定义
    • 函数的说明和调用
      • 函数调用的格式
      • 函数参数特点
      • 函数调用机制
      • 指针与函数
      • 函数性质
    • 标识符的作用域
    • 存储类

程序控制结构

预处理命令

所有的预处理命令在程序中都是以 “ # ” 开头,每一条预处理命令单独占一行,不用分号结束。预处理命令可以出现在程序中任何位置。

宏定义命令

C语言中用#define命令将一个指定的标识符(宏名)来代表一个字符串

#define 标识符 命令串
比如:#define PI 3.14

C++中,增加了const语句来定义符号常量

const 数据类型 变量名 = 常量;
const double PI = 3.14;

C++中,一般推荐用const语句来定义。

define除了可以定义常量之外,还可以用来定义语句,其格式如下:

#define ADD(a,b)  ((a) + (b))

计算a+b

#include<cstdio>
#define ADD(a,b) ((a) + (b))
int main()
{
	int num1 = 3;
	int num2 = 4;
	printf("%d",ADD(num1,num2));
	return 0;
}
输出结果:7

参考于: const和符号常量define的区别

语句

表达式语句

空语句
仅由一个分号(;)的语句,是一种不做任何操作的语句。
作用:程序中,语法上需要一个语句,但逻辑上并不需要,此时就可以用空语句。
例如,

for(i=1,s=0;i<=10;s+=i,i++);
//求1+2+...+10

最后的分号代表一条空语句,表示循环体不需要执行任何操作。

C++的9种控制语句

① if( )else (条件语句)
② for( )~ (循环语句)
③ while( )~ (循环语句)
④ do~while( ) (循环语句)
⑤ continue (结束本次循环语句)
⑥ break(中止执行switch或循环语句)
⑦ switch (多分支选择语句)
⑧ goto (转向语句)
⑨ return (从函数返回语句)

C语言讲过,简单看看就行。

数组

C++与C语言在数组上,无太大区别。因此就简单复习一下冒泡排序和选择排序算法。

冒泡排序
#include <iostream>
using namespace std;
int main()
{
	const int N = 5;
	int a[N]={5,6,8,1,4}; 
	int i,j,k,temp;
	for(i=0;i<N-1;i++) //N个数字比较N-1次 
	{
		for(j=0;j<N-i-1;j++)  //相邻的数字相比较 
		{
			if(a[j]>a[j+1])
			{
				temp=a[j];
				a[j]=a[j+1];
				a[j+1]=temp;
			}		
	   }
	}
	for(i=0;i<N;i++)
	{
		cout<<a[i]<<" "<<endl;
	}
}
选择排序
#include <iostream>
using namespace std;
int main()
{
	const int N=5;
	int a[N]={2,6,1,8,4};
	int i,j,k,temp;
	for(i=0;i<N-1;i++)
	{
		k=i;
		for(j=i+1;j<N;j++)
		{
			if(a[k]>a[j])
			{
				k=j;
			}			
		}
		temp=a[k];a[k]=a[i];a[i]=temp;
	}
	for(i=0;i<N;i++)
	{
		cout<<a[i]<<" "<<endl;
	}
	return 0;
}

函数

函数的定义

函数定义的一般形式

[static]
			返回值类型 函数名(形参表)
[extern]
{
	函数体
}

关键字
关键字“static”表明该函数为静态函数,这类函数仅限文件内使用。
关键字“extern”表明该函数为外部函数,这类函数也可以提供给程序内其他文件的函数进行调用。

返回值类型
"返回类型“可以是char、int、double等,在这些情况下,函数体内必须有return语句;如果函数没有返回值,返回类型应为void,此时,函数体内可以无return语句,或者return语句后什么也不写。

函数名
定义函数名与定义变量名规则一样,尽量避免用下划线开头,因为编译器常常定义一些下划线开头的变量或函数名。尽量做到”望文生义“,
例如:StudentNum(学生学号)采用驼峰式命名
主函数的函数名必须是main()。

形参表
形参(函数形式参数)
对应着,还有无参函数,形参表没有参数。

函数体
花括号里的语句称为函数体。

//设计一个函数,可以计算任意数的阶乘

long fac(int n) //任意数n
{
	long f=1;
	for(int i=1;i<=n;i++)
		f*=i;
	retutn f;
}

函数的说明和调用

函数定义和声明不是同一件事情
 函数定义是指对函数功能的确立,包括指定函数名、函数类型、形参及其类型、函数体等,它是一个完整的、独立的函数单位。
 函数声明的作用则是把函数的名字、函数类型以及形参的个数、类型和顺序(注意,不包括函数体)通知编译系统,以便在对包含函数调用的语句进行编译时,据此对其进行对照检查(例如函数名是否正确,实参与形参的类型和个数是否一致)。

函数调用的格式

常用的函数调用有两种方式:

对于有返回值的函数
	变量名 = 函数名(实参表);
对于无返回值的函数
	函数名(实参表);

//计算1到10阶乘倒数的和

#include <iostream>
using namespace std;
long fac(int n);
int main()
{
	double sum=0.0;
	for(int i=1;i<=10;i++)
		sum=sum + 1.0/fac(i);
	cout<<"sum="<<sum;
	return 0;
} 
//阶乘函数 
long fac(int n)
{
	long f=1;
	for(int i=1;i<=n;i++)
		f*=i;
	return f; 
}

编写时可以发现,函数可以在后面,但是前面使用时需要先声明。比如long fac(int n)对应着主函数中的sum=sum+1.0/fac(i)。
也可以发现,函数其实挺好用的,写一个函数,调用10次。

函数参数特点

函数形参:在函数未被调用的时候形参不占内存单元。
函数实参:实参必须要有类型,可以是常量,也可以是变量或表达式。
C++要求:函数调用时,函数的实参和形参个数相等,对应类型一致。

函数调用机制

①函数调用前,形参不占用内存单元,函数调用启动时,才临时给形参分配内存单元。
②将实参的值一一对应地传递给形参后,执行被调函数的函数体。
③系统释放形参所占内存单元。
④返回主调函数的调用点。

C++中,函数调用方式有两种,一是传值调用,二是引用调用。

传值调用
(实参传数给形参,形参获得实参的数值),改变形参不改变原先的实参,因为两者在获得值之后没有任何关系。
引用调用
(实参传地址给形参,形参获得实参的地址),改变形参会反映在存储单元中,实参会被改变。

注意
只有实参传值或者地址给形参!没有形参穿值或者地址给实参的说法!
形参没有确定的值,只能是变量。实参可以是常量、变量、表达式、函数。实参可以是表达式, 但不是“任意”,表达式计算结果的 类型 必须与 形参一致。当然数值不能超界溢出。

一般变量作为函数参数
例题:已知x=3,y=4,用公式d=根号(x^2 + y^2),求d的值。

#include <iostream>
#include <Cmath>
using namespace std;
double f(double x,double y)
{
	double z;
	x=x*x;
	y=y*y;
	z=sqrt(x+y);
	return z;	
}
int main()
{
	double f(double x,double y);
	double a,b,d;
	a=3.0;
	b=4.0;
	d=f(a,b);
	cout<<"a="<<a<<endl;
	cout<<"b="<<b<<endl;
	cout<<"d="<<d<<endl; 
}
运行结果:
a=3
b=4
d=5

可以看出,传值调用的特点是形参值的改变不影响实参。

指针与函数

指针用作参数
指针用作函数有两个特点:
①对于复杂类型,节省时间和空间,提高运行效率。
②方便实现函数之间的效率。
示例:

#include <iostream>
using namespace std;
int fun(int,int*);
int main()
{
	int x=5,y=9;
	cout<<x<<'\t'<<y<<endl;
	fun(x,&y);  //注意此处&y取址
	cout<<x<<'\t'<<y<<endl;
} 
int fun(int a,int *p)
{
	a=a*a;
	*p/=*p;
	cout<<a<<'\t'<<*p<<endl;
}
运行结果:
5       9   //输出x,y的值
25      1   //将x,y的值代入fun()函数中
5       1   //在主函数中输出x,y,可以发现y已经被改变。

在fun()函数中,形参p为指针,调用时,获得将实参y的地址值&y,使得形参指针指向实参变量y,这样,可以通过改变形参指针所指向的实参变量值间接改变实参值,从而实现函数之间的信息传递。

引用作为函数参数
引用定义的语法形式:

类型&引用名(变量名);
或
类型&引用名=变量名;

一般情况下,定义引用时必须初始化,同时引用的类型与变量的类型一致,例如:

int a=3;
int &m=a;   //或int &m(a)
此时,m是一个引用,m是变量a的别名。
m就像我们自己都有一个小名,代表的也是我们自己。
例如:m=m+1;  //此命令实质上就是a+1

所有在引用上进行的操作,实质上就是在被引用者上的操作。

指向函数的指针和指针函数
main()函数带参数

函数性质

默认函数值
C++中,允许在函数说明或定义时给一个或多个参数指定默认值。
设定规则如下:
①默认参数值的设置是在“函数说明”时进行的。
②默认参数值的设置遵循“靠后有值”原则。即当某个参数有默认值时,其后的参数必有默认值。
例如:

int fun(int a,int b=2,int c=5)
int fun(int a,int b=2,int c)
第二行就是错的,没有遵循靠后有值的原则。

感觉没啥意思,代码写规范点可以避免的,就做做考题吧。
函数设置默认的参数值示例:

#include <iostream>
using namespace std;
int fun(int a=1,int b=3,int c=5)
{
	cout<<a<<'\t'<<b<<'\t'<<c<<endl;
}
int main()
{
	fun();
	fun(4);
	fun(4,6);
	fun(4,6,8);
}
输出结果:
1 3 5
4 3 5
4 6 5
4 6 8

编译器按照从左到右的顺序将实参和形参结合,当实参的数目不足时,编译器将按同样顺序使用定义中的默认值来补足所缺少的实参。
一句话总结就是:从左至右,有就改,没就默认值。

内联函数
函数重复调用有利于提升开发效率,但是一旦函数调用频率过高,或者对于一些函数体比较小、比较简单的,多次调用,明显开销变大,效率就会降低。
因此为了节省这些开销,就引入了内联函数,在编译时将函数体嵌入调用处
语法格式

inline 返回值类型 函数名(形参表)
{
	函数体
}

使用时注意的问题
①内联函数体不宜过大(5行左右),且要结构简单。不允许出现循环语句和开关语句,也不能出现递归。
内联函数的定义必须出现在第一次被调用之前。(这个和函数不太一样)
③对内联函数不能进行异常接口声明。
④内联函数适合被频繁调用的小函数。

示例:
求5个数的最大值。要求编写并调用一函数实现2个数的较大值。

#include <iostream>
using namespace std;
inline int max(int x,int y)
{
	if(x>y)
		return x;
	else 
		return y;
}
int main()
{
	int a=34,b=56,c=22,d=100,e=88,m;
	m=max(a,b);
	m=max(m,c);
	m=max(m,d);
	m=max(m,e);
	cout<<"max="<<m<<endl;
} 
运行结果:
max=100

函数重载

赋予同一函数名称多个含义
最常见但是又不容易发现的,可能思维定势吧
例如:<<和>>,C语言学的时候明明就是按位与和按位或的符号,一个移位符号;而在C++中,它们却代表着输出和输入的符号。这就是运算符的重载,这里暂时不多说,有兴趣自行百度学习。

定义重载函数时,要求同名函数的参数表必须有差异,而对返回值的类型没有要求。重载函数的参数表差异有:参数的个数不同,或者至少有一个参数的类型不同。调用函数时,系统会根据实参与形参的个数和类型进行匹配,自动确定调用哪个函数。

函数的重载也称为多态函数。函数的重载一般出现在功能相近的函数之间。

递归函数

递归函数又叫自调用函数,其特点就是在函数内部直接或间接地自己调用自己
递归调用分为直接调用和间接调用两种方式。
直接递归调用是指在一个函数中实现调用自身的过程。
间接递归调用则是指在一个函数中调用其他函数,而在其他函数中又调用了本函数。
利用函数的递归调用,可以实现将复杂问题简单划,让计算机去执行简单问题的多次调用。
示例:用递归来算算这个
在这里插入图片描述
斐波那契数列:前两项数据均为1,以后的每项都是前两项之和。

#include <iostream>
using namespace std;
long F(unsigned n)
{
	if(n==0||n==1)
		return 1;
	else
		return F(n-1)+F(n-2);
}
int main()
{
	cout<<F(8)<<endl;
}
运行结果:
34

标识符的作用域

存储类

ps:还有点东西没时间写,赶着6级。为复习而用,比较粗糙。如有错误,欢迎指正!

这篇关于【C++】大纲及疑惑点二的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!