热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

c++:1

C第一部分介绍基础:c++:-0,本节介绍C中函数使用。##函数###函数调用调用函数需要先声明函数原型嵌套调用:###参数传递在函数被调用时才分配形参的存储单元实参可以是常量、变













C++第一部分介绍基础:c++:-0,本节介绍C++中函数使用。



函数


函数调用


调用函数需要先声明函数原型

嵌套调用:


参数传递



  • 在函数被调用时才分配形参的存储单元

  • 实参可以是常量、变量或表达式

  • 实参类型必须与形参相符

  • 值传递是传递参数值,即单向传递


  • 引用传递可以实现双向传递

  • 常引用作参数可以保障实参数据的安全



传引用比传对象计算消耗小



可变参数


C++中提供了两种方法:



  • 如果所有的实参类型相同,可以传递一个名为initializer_list的标准库类型;

  • 如果实参的类型不同,我们可以编写可变参数的模板。


initializer_list


initializer_list是一种标准库类型,用于表示某种特定类型的值的数组,该类型定义在同名的头文件中


使用:



  • 使用模板时,我们需要在模板名字后面跟一对尖括号,括号内给出类型参数。例如:

    initializer_list ls; // initializer_list的元素类型是string

    initializer_list li; // initializer_list的元素类型是int


  • initializer_list比较特殊的一点是,其对象中的元素永远是常量值,我们无法改变initializer_list对象中元素的值。

  • 含有initializer_list形参的函数也可以同时拥有其他形参


应用:



  • 在编写代码输出程序产生的错误信息时,最好统一用一个函数实现该功能,使得对所有错误的处理能够整齐划一。然而错误信息的种类不同,调用错误信息输出函数时传递的参数也会各不相同。

  • 使用initializer_list编写一个错误信息输出函数,使其可以作用于可变数量的形参。


内联函数



作用:编译时在调用处用函数体进行替换,节省了参数传递、控制转移等开销。



声明时使用关键字: inline

注意:



  • 内联函数体内不能有循环语句和switch语句;

  • 内联函数的定义必须出现在内联函数第一次被调用之前;

  • 对内联函数不能进行异常接口声明。


常量表达式


C++-11中新增,用于初始化常量表达式

(1)constexpr函数语法规定



  • constexpr修饰的函数在其所有参数都是constexpr时,一定返回constexpr;

  • 函数体中必须有且仅有一条return语句。


(2)constexpr函数举例


constexpr int get_size() { return 20; }
constexpr int foo = get_size(); //正确:foo是一个常量表达式

函数默认参数值


(1)默认参数值的说明次序



  • 有默认参数的形参必须列在形参列表的最右,即默认参数值的右面不能有无默认值的参数;

  • 调用时实参与形参的结合次序是从左向右。

    例:

    int add(int x, int y = 5, int z = 6);//正确

    int add(int x = 1, int y = 5, int z);//错误

    int add(int x = 1, int y, int z = 6);//错误

    (2)默认参数值与函数的调用位置

  • 如果一个函数有原型声明,且原型声明在定义之前,则默认参数值应在函数原型声明中给出;如果只有函数的定义,或函数定义在前,则默认参数值可以函数定义中给出。

    例:



重载函数



函数名相同,参数类型和返回类型不同;参数个数不同






系统函数


C++的系统库中提供了几百个函数可供程序员使用,例如:



  • 求平方根函数(sqrt)

  • 求绝对值函数(abs)

  • 正弦值、余弦值和正切值的函数:sin()、cos()、tan()

    使用系统函数时要包含相应的头文件,例如:cmath


举例


计算n次方



计算x的n次方



#include 

using namespace std;
//计算x的n次方
double power(double x, int n) {
double val = 1.0;
while (n--) val *= x;
return val;
}
int main() {
cout <<"5 to the power 2 is "
< return 0;
}

进制转换(8-10)



输入一个8位二进制数,将其转换为十进制数输出。



#include 
using namespace std;

double power (double x, int n); //计算x的n次方

int main() {
int value = 0;
cout <<"Enter an 8 bit binary number ";
//cin:只有在输入完数据再按回车键后,该行数据才被送入键盘缓冲区,形成输入流,提取运算符“>>”才能从中提取数据。需要注意保证从流中读取数据能正常进行。
for (int i = 7; i >= 0; i--) {
char ch;
cin >> ch;
if (ch == '1')
value += static_cast(power(2, i));//tatic_cast()强制类型转换
}
cout <<"Decimal value is " < return 0;
}
double power (double x, int n) {
double val = 1.0;
while (n--)
val *= x;
return val;
}

计算π



π的计算公式如下:




#include 
using namespace std;
//求arctan
double arctan(double x) {
double sqr = x * x;
double e = x;
double r = 0;
int i = 1;
while (e / i > 1e-15) {
double f = e / i;
r = (i % 4 == 1) ? r + f : r - f;
e = e * sqr;
i += 2;
}
return r;
}

int main() {
double a = 16.0 * arctan(1/5.0);
double b = 4.0 * arctan(1/239.0);
//注意:因为整数相除结果取整,如果参数写1/5,1/239,结果就都是0
cout <<"PI = " < return 0;
}

寻找回文数



寻找并输出11~999之间的数M,它满足\(M、M^2和M^3\)均为回文数。

回文:各位数字左右对称的整数。

例如:11满足上述条件:112=121,113=1331。



分析:

用除以10取余的方法,从最低位开始,依次取出该数的各位数字。按反序重新构成新的数,比较与原数是否相等,若相等,则原数为回文。


#include 

using namespace std;
//判断n是否为回文数
bool symm(unsigned n) {
unsigned i = n;
unsigned m = 0;
while (i > 0) {
m = m * 10 + i % 10;
i /= 10;
}
return m == n;
}

int main() {
for(unsigned m = 11; m <1000; m++)
if (symm(m) && symm(m * m) && symm(m * m * m)) {
cout <<"m = " < cout <<" m * m = " < cout <<" m * m * m = "
< }
return 0;
}

分段函数



计算分段函数,并输出结果





分析:

计算\(sin(x)\)的公式,精度为\(10^{-10}\)


#include "iostream"
#include "cmath"

using namespace std;

const double T=1e-10; //定义计算精度10^{-10}

//计算sin(x)
double tsin(double x)
{
double g=0;
double t=x;
int n=1;
do{
g+=t;
n++;
t=-t*x*x/(2*n-1)/(2*n-2);
}while(fabs(t)>=T);//fabs:绝对值
return g;
}

int main()
{
double k,r,s;
cout <<"r=";
cin >>r;
cout <<"s=";
cin >>s;
if(r*r<=s*s)
{
k= sqrt(tsin(r)*tsin(r)+tsin(s)*tsin(s));
}else
k=tsin(r*s)/2;
cout < return 0;
}

掷骰子



每个骰子有六面,点数分别为1、2、3、4、5、6。游戏者在程序开始时输入一个无符号整数,作为产生随机数的种子。每轮投两次骰子,第一轮如果和数为7或11则为胜,游戏结束;和数为2、3或12则为负,游戏结束;和数为其它值则将此值作为自己的点数,继续第二轮、第三轮...直到某轮的和数等于点数则取胜,若在此前出现和数为7则为负。



分析:

(1)rand函数

函数原型:int rand(void);

所需头文件:

功能和返回值:求出并返回一个伪随机数


(2)srand函数

void srand(unsigned int seed);

参数:seed产生随机数的种子

所需头文件:

功能:为使rand()产生一序列伪随机整数而设置起始点。使用1作为seed参数,可以重新初化rand()。


#include "iostream"
#include "cmath"

using namespace std;
enum GameStatus{Win,Lose,Playing};//枚举存储状态

//掷骰子,计算和数,输出和数
int rollDice()
{
int die1=1+rand()%6;
int die2=1+rand()%6;
int sum=die1+die2;
cout < return sum;
}


int main()
{
int sum,myPoint;
GameStatus status;
unsigned seed;
int rollDice();
cout <<"请输入种子:";
cin >> seed;
srand(seed);//将种子传给rand()
sum=rollDice();//第一轮掷骰子
switch (sum) {
case 7:
case 11:
status=Win;
break;
case 2:
case 3:
case 12:
status=Lose;
break;
default:
status=Playing;
myPoint=sum;
cout <<"点数为"< break;
}
//第二轮以后
while (status==Playing)
{
sum=rollDice();
if(sum==myPoint) //某轮和数等于点数取胜
{
status=Win;
}else if(sum ==7)//出现和数为7则负
{
status=Lose;
}
}
//输出
if(status==Win)
{
cout <<"Win"< } else
cout <<"Lose" < return 0;
}


疑问:为什么die1和die2是一样的?

种子一样!



    srand(2);
int die1=1+rand()%6;
srand(1);
int die2=1+rand()%6;
cout<

求组合数



#include 

using namespace std;
int commit(int n,int k)
{
if(k>n)
return 0;
else if(n==k || k==0)
return 1;
else
return commit(n-1,k)+ commit(n-1,k-1);
}

int main() {
int n,k;
cout <<"请输入n和k:";
cin >> n>>k;
cout <<"C("< return 0;
}

汉诺塔问题



有三根针A、B、C。A针上有N个盘子,大的在下,小的在上,要求把这N个盘子从A针移到C针,在移动过程中可以借助B针,每次只允许移动一个盘,且在移动过程中在三根针上都保持大盘在下,小盘在上。



分析:

将n 个盘子从A针移到C针可以分解为三个步骤:



  • 将A 上n-1个盘子移到 B针上(借助C针);

  • 把A针上剩下的一个盘子移到C针上;

  • 将n-1个盘子从B针移到C针上(借助A针)。


#include 
using namespace std;

//将src针的最上面一个盘子移动到dest针上
void move(char src, char dest) {
cout < " <}

//将n个盘子从src针移动到dest针,以medium针作为中转
void hanoi(int n, char src, char medium, char dest)
{
if (n == 1)
move(src, dest);
else {
//将A 上n-1个盘子移到 B针上(借助C针);
hanoi(n - 1, src, dest, medium);
//把A针上剩下的一个盘子移到C针上;
move(src, dest);
//将n-1个盘子从B针移到C针上(借助A针)
hanoi(n - 1, medium, src, dest);
}
}
int main() {
int m;
cout <<"Enter the number of diskes: ";
cin >> m;
cout <<"the steps to moving " < hanoi(m,'A','B','C');
return 0;
}

值交换



输入两个整数并交换

分析:

参数传递有两种:值传递和引用传递

引用就是别名,定义int &a=i;



值传递,并没有交换


#include
using namespace std;
void swap(int a, int b) {
int t = a;
a = b;
b = t;
}

int main() {
int x = 5, y = 10;
cout<<"x = "<


#include
using namespace std;

//a和b分别是x和y的引用
void swap(int& a, int& b) {
int t = a;
a = b;
b = t;
}

int main() {
int x = 5, y = 10;
cout<<"x = "<内联函数
#include 
using namespace std;

const double PI = 3.14159265358979;
inline double calArea(double radius) {
return PI * radius * radius;
}

int main() {
double r = 3.0;
double area = calArea(r);
cout < return 0;
}

计算长方体的体积



有三个形参:length(长)、width(宽)、height(高),其中width和height带有默认值2和3。



#include 
#include
using namespace std;

int getVolume(int length, int width = 2, int height = 3);//声明在前,定义默认参数值
int main() {
const int X = 10, Y = 12, Z = 15;
cout <<"Some box data is " ;
cout < cout <<"Some box data is " ;
cout < cout <<"Some box data is " ;
cout < return 0;
}
//定义中不定义默认参数值
int getVolume(int length, int width, int height) {
cout < < return length * width * height;
}

重载函数



编写两个名为sumOfSquare的重载函数,分别求两整数的平方和及两实数的平方和。



#include 
using namespace std;
//类型不同
int sumOfSquare(int a, int b) {
return a * a + b * b;
}
double sumOfSquare(double a, double b) {
return a * a + b * b;
}
int main() {
int m, n;
cout <<"Enter two integer: ";
cin >> m >> n;
cout<<"Their sum of square: "< double x, y;
cout <<"Enter two real number: ";
cin >> x >> y;
cout<<"Their sum of square: "< return 0;
}

求正弦值、余弦值和正切值



从键盘输入一个角度值,求出该角度的正弦值、余弦值和正切值。



#include 
#include
using namespace std;
const double PI = 3.14159265358979;

int main() {
double angle;
cout <<"Please enter an angle: ";
cin >> angle; //输入角度值
double radian = angle * PI / 180; //转为弧度
cout <<"sin(" <习题

(1)已知函数FA调用FB,若要把这两个函数定义在同一个文件中,则



  • FA必须定义在FB之前

  • FB必须定义在FA之前

  • 若FA定义在FB之后,则FA的原型必须出现在FB的定义之前

  • 若FB定义在FA之后,则FB的原型必须出现在FA的定义之前(对)



函数原型,就是函数的声明



(2)在()时为形参分配存储空间。



  • 函数声明

  • 函数定义

  • 函数调用(对)


(3)可以定义指向引用的指针.

错。因为引用不是对象,引用并没有在程序中占据内存空间,故没有地址的说法.

(4)类内实现好的成员函数是内联函数,在类体外实现的函数不能是内联函数

错。因为内联函数主要的作用是在某些情况(某个函数被调用多次)下可以提高程序的运行效率。定义内联函数,可以显式用inline声明,也可以直接在类内定义好实现. 扩展阅读

(5)已知程序中有以下声明:



  • int nonconst_var = 100;

  • const int const_var1 = 2;

  • const int const_var2 = nonconst_var;

    则下述代码中正确的是:

  • constexpr int constexpr_var1 = 3 + const_var1 * 4; (对)

  • constexpr int constexpr_var2 = 3 + nonconst_var * 4;

  • constexpr int constexpr_var3 = 3 + const_var2 * 4;


分析:

constexpr的变量的值必须是编译器在编译的时候就可以确定的。上例中因为nonconst_var的值在语法上来讲,运行期间可能被更改,所以编译期间无法确定,不属于常数表达式。因为const_var2是由非常数表达式来初始化的,所以const_var2也不是常数表达式。但const_var2本身的声明,定义及初始化是合法的。constexpr比const更严格,用来初始化constexpr_var2和constexpr_var3的也都不是常数表达式,所以他们的定义都是错误的。

(6)例3-15中的getVolume函数,如果直接调用int a=getVolume();后,会有什么样的结果?



  • 编译运行正确,a的值为0

  • 编译运行正确,a的值为6

  • 编译报错(对)

  • 运行出错

    分析:

    函数有一个形参没有默认值,所以至少要提供一个实参。注意,默认不是0


(7)判断两个浮点数是否相等


abs(a-b)<1e-10  //abs求绝对值

















推荐阅读
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • 使用 Azure Service Principal 和 Microsoft Graph API 获取 AAD 用户列表
    本文介绍了一段通用代码示例,该代码不仅能够操作 Azure Active Directory (AAD),还可以通过 Azure Service Principal 的授权访问和管理 Azure 订阅资源。Azure 的架构可以分为两个层级:AAD 和 Subscription。 ... [详细]
  • 本文详细介绍了Java中org.neo4j.helpers.collection.Iterators.single()方法的功能、使用场景及代码示例,帮助开发者更好地理解和应用该方法。 ... [详细]
  • 本文详细介绍了如何在Linux系统上安装和配置Smokeping,以实现对网络链路质量的实时监控。通过详细的步骤和必要的依赖包安装,确保用户能够顺利完成部署并优化其网络性能监控。 ... [详细]
  • 深入理解 SQL 视图、存储过程与事务
    本文详细介绍了SQL中的视图、存储过程和事务的概念及应用。视图为用户提供了一种灵活的数据查询方式,存储过程则封装了复杂的SQL逻辑,而事务确保了数据库操作的完整性和一致性。 ... [详细]
  • 在前两篇文章中,我们探讨了 ControllerDescriptor 和 ActionDescriptor 这两个描述对象,分别对应控制器和操作方法。本文将基于 MVC3 源码进一步分析 ParameterDescriptor,即用于描述 Action 方法参数的对象,并详细介绍其工作原理。 ... [详细]
  • 本文深入探讨了 Java 中的 Serializable 接口,解释了其实现机制、用途及注意事项,帮助开发者更好地理解和使用序列化功能。 ... [详细]
  • 本文详细介绍了Akka中的BackoffSupervisor机制,探讨其在处理持久化失败和Actor重启时的应用。通过具体示例,展示了如何配置和使用BackoffSupervisor以实现更细粒度的异常处理。 ... [详细]
  • Python 异步编程:深入理解 asyncio 库(上)
    本文介绍了 Python 3.4 版本引入的标准库 asyncio,该库为异步 IO 提供了强大的支持。我们将探讨为什么需要 asyncio,以及它如何简化并发编程的复杂性,并详细介绍其核心概念和使用方法。 ... [详细]
  • Explore how Matterverse is redefining the metaverse experience, creating immersive and meaningful virtual environments that foster genuine connections and economic opportunities. ... [详细]
  • 本文总结了2018年的关键成就,包括职业变动、购车、考取驾照等重要事件,并分享了读书、工作、家庭和朋友方面的感悟。同时,展望2019年,制定了健康、软实力提升和技术学习的具体目标。 ... [详细]
  • 深入解析Spring Cloud Ribbon负载均衡机制
    本文详细介绍了Spring Cloud中的Ribbon组件如何实现服务调用的负载均衡。通过分析其工作原理、源码结构及配置方式,帮助读者理解Ribbon在分布式系统中的重要作用。 ... [详细]
  • 解决PHP与MySQL连接时出现500错误的方法
    本文详细探讨了当使用PHP连接MySQL数据库时遇到500内部服务器错误的多种解决方案,提供了详尽的操作步骤和专业建议。无论是初学者还是有经验的开发者,都能从中受益。 ... [详细]
  • 将Web服务部署到Tomcat
    本文介绍了如何在JDeveloper 12c中创建一个Java项目,并将其打包为Web服务,然后部署到Tomcat服务器。内容涵盖从项目创建、编写Web服务代码、配置相关XML文件到最终的本地部署和验证。 ... [详细]
author-avatar
靜钕孓626
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有