C++函数的定义与使用

2023-10-28

函数的定义和使用

main就是一个函数,它是C++程序的主函数。一个C++程序可以由一个主函数和若干子函数组成。主函数是程序执行的开始点。由主函数调用子函数,子函数还可以再调用其它子函数。

调用其它函数的函数称为主调函数。被其他函数调用的函数称为被调函数。一个函数很可能既调用别的函数又被其它函数调用。

1.函数的定义

1.1函数定义的语法形式

类型说明符   函数名(含类型说明的形式参数表)

{

   语句序列

}

1.2形式参数

类型标识符1   形参名1,类型标识符2   形参名2,···,类型标识符n   形参名n

形参的作用是实现主调函数与被调函数之间的联系。通常将函数所处理的数据、影响函数功能的因素或者函数的处理结果作为形参。

如果一个函数的形参表为空,则表示它没有任何形参。main函数可以没有形参,也可以有形参,其形参也称命令行参数,由操作系统在启动程序时初始化。

函数在没有被调用时是静止的,此时的形参只是一个符号,它标志着在形参出现的位置应该有一个什么类型的数据。

函数在被调用时才执行,也就是在被调用时才由主调函数将实际参数赋予形参。

1.3函数的返回值和返回值类型

函数可以有一个返回值,函数的返回值是需要返回给主调函数的处理结果。类型说明符规定了函数返回值的类型,函数的返回值由return语句给出,格式如下:

return 表达式;

除了指定函数的返回值外,return语句还有一个作用,就是结束当前函数的执行

一个函数也可以不讲任何值返回给主调函数,这时它的类型标识符为void,可以不写return语句,但也可以写一个不带表达式的return语句,用于结束当前函数的调用,格式如下:

return;

2.函数的调用

2.1函数的调用形式

变量在使用之前需要首先声明,类似的,函数在调用之前也需要声明。函数的定义就属于函数的声明,因此,在定义了一个函数之后,可以直接调用这个函数。但如果希望在定义一个函数之前调用它,则需要在调用函数之前添加该函数的函数原型声明。函数原型声明的形式如下:

类型说明符   函数名(含类型说明的形参表);

与变量的声明和定义类似,声明一个函数只是将函数的有关信息告诉编译器,此时并不产生任何代码;定义一个函数是除了同样要给出函数的有关信息外,主要是要写出函数的代码。

声明了函数原型之后,便可以按如下形式调用子函数:

函数名(实参列表);

实参列表应该给出与函数原型形参个数相同、类型相符的实参,每个实参都是一个表达式。函数调用可以作为一条语句,这时函数可以没有返回值。函数调用也可以出现在表达式中,这时就必须有一个明确的返回值。

 

例1   编写一个求x的n次方的函数

#include<iostream>
using namespace std;
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"<<power(5,2)<<endl;
return 0;


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

#include<iostream>
using namespace std;
double power(double x,int n);
int main(){
int value=0;
cout<<"Enter an 8 bit binary number: ";
for(int i=7;i>=0;i--)
{
char ch;
cin>>ch;
if(ch=='1')
value+=static_cast<int>(power(2,i));
}
cout<<"Decimal value is"<<value<<endl;
return 0;
}
double power(double x,int n)
{
double val=1.0;
while(n--)
val*=x;
return val;

}

注意:ch的类型写成int是不正确的


例3 编写程序求π的值,公式如下:

π=16arctan(1/5)-4arctan(1/239)

其中arctan用如下形式的级数计算:

   arctanx=x-x^3/3+x^5/5-x^7/7+···

直到级数某项绝对值不大于10^-15为止;π和x均为double型。

#include<iostream>
using namespace std;
double arctan(double x)
{
double sqr=x*x;
double e=x;
double r=0;
int i=1;
while(e/i>1e-15)//1e-15是科学记数法的1*10的-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);
cout<<"PI="<<a-b<<endl;
return 0;
}


例4  寻找并输出11~999之间的数m,它满足m,m^2,m^3均为回文数

所谓回文数是指其各位数字左右对称的整数。例如,121,676,94249等。满足上述条件的数如m=11,m^2=121,m^3=1331.

分析:判断一个数是否是回文数,可以用除以10求余的方法,从最低位开始,依次取出该数的各位数字,然后用最低位充当最高位,按反序重新构成新的数,与原数比较是否相等,若相等,则原数为回文。

#include<iostream>
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<=999;m++)
{
if(symm(m)&&symm(m*m)&&symm(m*m*m))
{
cout<<"m="<<m;
cout<<"   m*m="<<m*m;
cout<<"   m*m*m="<<m*m*m<<endl;
}
}
return 0;
}

 

例5 投骰子的随机游戏

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

有rollDice函数负责模拟投骰子,计算和数并输出和数。

提示  系统函数int rand(void)的功能是产生一个伪随机数,伪随机数并不是真正随机的。这个函数自己不能产生真正的随机数。如果在程序中连续调用rand,期望由此可以产生一个随机数序列,你会发现每次运行这个程序时产生的序列都是相同的,这称为伪随机数序列。这是因为函数rand需要一个称为”种子“的初始值,种子不同,产生的伪随机数也就不同。因此只要每次运行时给予不同的种子,然后连续调用rand便可以产生不同的随机数序列。如果不设置种子,rand总是默认种子为1。不过设置种子的方法比较特殊,不是通过函数的参数,而是在调用它之前,需要首先调用另外一个函数void srand(unsigned int seed)为其设置种子,其中的参数seed便是种子。

#include<iostream>
#include<cstdlib>
using namespace std;


int rollDice(){
int die1=1+rand()%6;
int die2=1+rand()%6;
int sum=die1+die2;
cout<<"Player rolled"<<die1<<"+"<<die2<<"="<<sum<<endl;
return sum;
}
enum GameStatus{WIN,LOSE,PLAYING};
int main()
{
int sum,myPoint;
    GameStatus status;


unsigned seed;
cout<<"Please enter an unsigned integer:";
cin>>seed;
srand(seed);


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<<"point is"<<myPoint<<endl;
break;
}
while(status==PLAYING)
{
sum=rollDice();
if(sum==myPoint)
status=WIN;
else if(sum==7)
status=LOSE;


}
if(status==WIN)
cout<<"player wins"<<endl;
else
cout<<"player loses"<<endl;
return 0;
}

2.2嵌套调用

函数允许嵌套调用。如果函数1调用了函数2,函数2再调用函数3,便形成了函数的嵌套调用

例 输入两个整数,求他们的平方和。

分析:设计两个函数:求平方和函数fun1和求一个整数的平方函数fun2。由主函数调用fun1,fun1又调用fun2。

#include<iostream>
using namespace std;
int fun2(int m)
{
return m*m;
}
int fun1(int x,int y)
{
return fun2(x)+fun2(y);
}
int main()
{
int a,b;
cout<<"Please enter two integers(a and b):";
cin>>a>>b;
cout<<"The sum of square of a and b:"<<fun1(a,b)<<endl;
return 0;

}

2.3递归调用

函数可以直接或间接地调用自身,称为递归调用。

所谓直接调用自身,就是指在一个函数的函数体中出现了对自身的调用表达式,例如:

void fun1()

{

···

fun1();     //调用fun1()自身

···

   

}

这就是函数直接调用自身的例子。

而下面的情况是函数间接调用自身:

void fun1()

{

···

fun2();

···

}

void fun2()

{

···

fun1();

···

}

这里fun1调用了fun2,而fun2又调用了fun1,于是构成了递归。

递归算法的实质是将原有的问题分解成新的问题,而解决新问题时又用到了原有问题的解法。按照这一原则分解下去,每次出现的新问题都是原有问题的简化的子集,而最终分解出来的问题,是一个已知解的问题。这便是有限的递归调用。只有有限的递归调用才是有意义的,无限的递归调用永远得不到解,没有实际意义。

递归的过程有如下两个阶段。

第一阶段:递推。将原问题不断分解为新的子问题,逐渐从未知向已知推进,最终达到已知的条件,即递归结束的条件,这时递推阶段结束。

例如,求5!,可以这样分解:

5!=5*4!—>4!=4*3!—>3!=3*2!—>2!=2*1!—>1!=1*0!—>0!=1

未知----------------------------------------------------------->已知

第二阶段:回归。从已知的条件出发,按照递推的逆过程,逐一求值回归,最后达到递推的开始处,结束回归阶段,完成递归调用。

例如,求5!的回归阶段如下:

5!=5*4!<—4!=4*3!<—3!=3*2!<—2!=2*1!<—1!=1*0!<—0!=1

未知<-----------------------------------------------------------已知

例1 求n!

分析:当n=0时,n!=1;

          当n>0时,n!=n*(n-1)!

递归结束的条件是n=0。

#include<iostream>
using namespace std;
unsigned fac(unsigned n)
{
unsigned f;
if(n==0)
f=1;
else
f=fac(n-1)*n;
return f;
}
int main()
{
unsigned n;
cout<<"Enter a positive integer:";
cin>>n;
unsigned y=fac(n);
cout<<n<<"!="<<y<<endl;
return 0;

}

注意:对同一个函数的多次不同调用中,编译器会为函数的形参和局部变量分配不同的空间,他们互不影响。

例2 用递归法计算从n个人中选择k个人组成一个委员会的不同组合数。

分析:由n个人里选k个人的组合数=由n-1个人里选k个人的组合数+由n-1个人里选k-1个人的组合数

由于计算公式本身是递归的,因此可以编写一个递归函数来完成这一功能,递推的结束条件是n=k或n=0,这时的组合数是1,然后开始回归。

#include<iostream>
using namespace std;
int comm(int n,int k)
{
if(n<k)
return 0;
else if(n==k||k==0)
return 1;
else
return comm(n-1,k)+comm(n-1,k-1);
}
int main()
{
int n,k;
cout<<"Please enter two integers n and k:";
cin>>n>>k;
cout<<"C(n,k)="<<comm(n,k)<<endl;
return 0;

}

例3 汉诺塔问题

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

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

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

(2)将A针上剩下的一个盘子移到C针上;

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

事实上,上面三个步骤包含下面两种操作:

(1)将多个盘子从一个针移动到另一个针上,这是一个递归的过程。

(2)将一个盘子从一个针移到另一个针上。

#include<iostream>
using namespace std;
void move(char src,char dest)
{
cout<<src<<"-->"<<dest<<endl;
}
void hanoi(int n,char src,char medium,char dest)
{
if(n==1)
move(src,dest);
else
{
hanoi(n-1,src,dest,medium);
move(src,dest);
hanoi(n-1,medium,src,dest);
}
}
int main()
{
int m;
cout<<"Enter the number of disks:";
cin>>m;
cout<<"the steps to moving"<<m<<"disks:"<<endl;
hanoi(m,'A','B','C');
return 0;

}

3.函数的参数传递

在函数未被调用时,函数的形参并不占有实际的内存空间,也没有实际的值。只有在函数被调用时才为形参分配存储单元,并将实参与形参结合。每个实参都是一个表达式,其类型必须与形参相符。函数的参数传递指的就是形参与实参结合(简称形实结合)的过程,形实结合的方式有值传递和引用传递。

3.1值传递

值传递是指当发生函数调用时,给形参分配内存空间,并用实参来初始化形参(直接将实参的值传递给形参)。这一过程是参数值的单项传递过程,一旦形参获得了值便与实参脱离关系,此后无论形参发生了怎样的改变,都不会影响到实参。

例1

将两个整数变换次序后输出

#include<iostream>
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="<<x<<"   y="<<y<<endl;
swap(x,y);
cout<<"x="<<x<<"   y="<<y<<endl;
return 0;

}

分析:从上面的运行结果可以看出,并没有达到交换的目的。这是因为,采用的是值传递,函数调用时传递的是实参的值,是单向传递过程。形参值的改变对实参不起作用。

2.引用传递

值传递时参数是单向传递。

引用是一种特殊类型的变量,可以被认为是另一个变量的别名,通过引用名与通过被引用的变量名访问变量的效果是一样的。例如:

int i,j;

int &ri=i;  //建立一个int型的引用ri,并将其初始化为变量i的一个别名

j=10;

ri=j;         //相当于i=j

使用引用时必须注意以下问题:

·声明一个引用时,必须同时对它进行初始化,使它指向一个已存在的对象。44

·一旦一个引用被初始化后,就不能改为指向其它对象。

也就是说,一个引用,从它诞生时,就必须确定是哪个变量的别名,而且始终只能作为作为这一个变量的别名,不能另作他用。

引用也可以作为形参,如果将引用作为形参,情况便稍有不同。这是因为,形参的初始化不在类型说明时进行,而是在执行主调函数中的调用表达式时,才为形参分配内存空间,同时用实参初始化形参。这样引用类型的形参就通过形实结合,成为了实参的一个别名,对形参的任何操作也就会直接作用于实参。

用引用作为形参,在函数调用时发生的参数传递,称为引用传递。

例2 使用引用传递改写例1,使两整数成功的进行交换

#include<iostream>
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="<<x<<"   y="<<y<<endl;
swap(x,y);
cout<<"x="<<x<<"   y="<<y<<endl;
return 0;

}

例3

值传递与引用传递的比较

#include<iostream>
#include<iomanip>
using namespace std;


void fiddle(int in1,int &in2)
{
in1=in1+100;
in2=in2+100;
cout<<"The values are";
cout<<setw(5)<<in1;
cout<<setw(5)<<in2<<endl;
}
int main()
{
int v1=7,v2=12;
cout<<"The values are";
cout<<setw(5)<<v1;
cout<<setw(5)<<v2<<endl;
fiddle(v1,v2);
cout<<"The values are";
cout<<setw(5)<<v1;
cout<<setw(5)<<v2<<endl;
return 0;
}










本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++函数的定义与使用 的相关文章

  • 后端data的存储

    一 数据的格式 创建一个名为data的文件夹 创建文件userlist json的文件用来存储数据 7w username 7w password 6512bd43d9caa6e02c990b0a82652dca create time 2
  • NJU-ICS-linklab 从零开始复习程序的链接与ELF

    linklab实验记录 实验题目及材料 https github com qmj0923 NJU ICS linklab 实验环境 debian 10 5 0 i386 netinst虚拟机 gcc Debian 8 3 0 6 8 3 0
  • 【算法竞赛宝典】插入排序

    算法竞赛宝典 插入排序 题目描述 伪代码 代码展示 代码讲解 题目描述 伪代码 代码展示 插入排序数 请自己根据例程修改 include
  • pycharm Git reset

    天下苦不会用git久矣 所以记录一下 一 回到原先某一时刻版本 如果后面的commit都不想要了 就想回到前面的某个时间 在本地要 在远程也得改head 在local命令利用 git push origin HEAD force
  • Web安全—暴力破解(pikachu)

    Web安全 暴力破解 BurteForce 前言 弱口令yyds 暴力破解虽然是一种原理特别简单的漏洞 其利用方式也非常简单 但其危害却十分巨大 如果我们通过信息阶段找到Web应用的后台登陆页面 然后通过弱口令 暴力破解登陆 那这个Web应
  • Git(六):基本命令(3):储藏、标签、拉取、子模块

    目录 17 stash 储藏 17 2 描述 17 3 基本用法 18 tag 标签 18 1 描述 18 2 基本用法 19 fetch 获取 19 1 描述 19 2 基本用法 20 pull 整合 20 1 描述 20 2 基本用法
  • TypeError: '>' not supported between instances of 'str' and 'float'

    目录 含义 出现原因 情况一纠正措施 情况二纠正措施 含义 类型错误 浮点数和字符串之间无法比较 出现原因 出现这种错误类型 目前遇到了两种情况 如下 一 对excel的两列数据进行字典键与键值对应操作时 键值列数据既存在浮点数类型又存在字
  • Callable接口、Runable接口、Future接口

    1 Callable与Runable区别 Java从发布的第一个版本开始就可以很方便地编写多线程的应用程序 并在设计中引入异步处理 Thread类 Runnable接口和Java内存管理模型使得多线程编程简单直接 但Thread类和Runn
  • 蓝桥杯评分标准_蓝桥杯比赛要求

    七 奖项设置及评选办法 7 1 省赛 1 参赛选手奖 省赛每个组别设置一 二 三等奖 比例分别为 10 20 30 总比例为实际参赛人数 的 60 零分卷不得奖 省赛一等奖选手获得直接进入全国总决赛资格 所有获奖选手均 可获得由工业和信息化
  • ABA问题及解决

    ABA问hiyi题 在多线程环境下 一个线程需要修改共享变量的值 使用CAS操作时 当其他线程将该共享变量由A该为B 再将B改为A后 这个线程依然可以CAS操作成功 因为这个线程不能感知这个共享变量被修改过 解决方法 给共享变量增加一个版本
  • spring cloud gateway项目启动报错

    spring cloud gateway项目启动报错 Correct the classpath of your application so that it contains a single compatible version of
  • Nginx之keepalive配置解读

    目录 keepalive基础介绍 Nginx中的keepalive配置项 应用场景 什么时候使用 什么时候不用 keepalive基础介绍 keepalive是HTTP 1 1协议中的一个特性 它允许客户端和服务器之间的TCP连接在一个HT
  • 使用file.transferTo(tempFile)保存文件,第二次操作时却报错:请求的操作无法在使用用户映射区域打开的文件上执行。

    背景是我要做个后台管理上表格的导入导出excel的功能 导出没有什么问题 但一到导入就开始出了问题 我用的是xxl excel工具 在导入时接收一个MultipartFile file 然后new一个新文件 再利用file transfer
  • 8-js高级-3

    JavaScript 进阶 3 了解构造函数原型对象的语法特征 掌握 JavaScript 中面向对象编程的实现方式 基于面向对象编程思想实现 DOM 操作的封装 编程思想 构造函数 原型 综合案例 编程思想 学习 JavaScript 中
  • pclint入门

    1 安装 将压缩包比如pclint8 zip拷贝到c 解压后重命名目录为c pclint 版本 Q 如何查看版本 A 见readme txt PC lint for C C Version 8 00e 2 开始使用 2 1 不用任何配置 直
  • 第十二章:使用C语言(Python语言)操作Sqlserver2019数据库

    目录 一 连接数据库的准备工作 二 使用 ODBC 连接数据库 1 ODBC 数据源简介 2 配置 ODBC 数据库源 3 连接数据库函数 4 C 语言通过 ODBC 操作数据库 三 非 ODBC 方式操作数据库 3 1 删除 修改 插入数
  • java 僵尸进程_僵尸进程ZOMBIE

    僵尸进程是指它的父进程已经退出 父进程没有等待 调用wait waitpid 它 而该进程dead之后没有进程接受 就成为僵尸进程 也就是 zombie 进程 一个进程在调用exit命令结束自己的生命的时候 其实它并没有真正的被销毁 而是留
  • 梦幻服务器系统维护后多久再登录,梦幻西游:系统维护后出现重大漏洞,官方发文紧急停机修复?...

    原标题 梦幻西游 系统维护后出现重大漏洞 官方发文紧急停机修复 精彩游戏 快乐无穷无尽 这里是梦幻西游资讯集中营 每天为你分享不一样的游戏乐趣 大家好 我是梦幻小九 当今社会网络游戏成千上万个 相信每一款网络游戏都会偶尔出现系统漏洞 梦幻西
  • 西门子PLC300系列与上位机无法建立以太网通信问题

    问题描述 最近做一个Java开发的WCS项目需要对接机械臂 使用的是PLC313型号 按照之前和其他型号PLC例如1200系列或者1500系列对接的经验配置好相关IP DB块以及数据结构偏移量以后发现无法建立连接 刚开始以为是使用是git上
  • keil编译运行错误,缺少error:#5:#includecore_cm3.h_过路老熊_新浪博客

    keil编译运行错误 提示缺少某个文件等等 如缺少error 5 include core cm3 h 用Keil vision5编译时出现以下错误 error 5 cannot open source input file core cm

随机推荐

  • Java EE 企业级应用 复习 初识Spring框架

    Spring概述 Spring是由Rod Johnson组织开发的一个分层的Java SE EE一站式轻量级开源框架 它最核心的理念是控制反转和面向切面编程 Spring框架的优点 非倾入式设计 降低耦合性 方便开发 支持AOP编程 支持声
  • Linux之Centos7.6版本下载及安装Go语言环境配置,安装Go1.18版本教程笔记-2023版

    文章目录 一 Linux下安装Go环境 1 远程获取 2 解压 3 添加环境变量 5 Go环境配置图 配置完成信息图 二 VsCode连接我们Go 2 1安装对应的插件 2 2进行连接 3 相关配置 4 成功连接 一 Linux下安装Go环
  • 视频在H5页面在微信浏览器不能自动播放问题

    引用官方的JS文件 正式方法 function BGMAutoPlayMgr url this audioContext new window AudioContext window webkitAudioContext window mo
  • 2020那些搭载Imagination IP的设备(国内篇)

    除海外市场外 2020年国内不少智能新品上市 并通过搭载ImaginationGPU 和 NNA IP 实现了更加明显的市场差异化 基于紫光展锐虎贲T7510 平台国内多款 5G 手机上市 智能手机市场 5G AI 无疑成为下一代手机的焦点
  • Unity调用Android类方法

    1 添加Unity的classes jar文件 创建一个Android工程AndroidUnityDemo 由于Unity的版本不同 直接在Unity安装包文件夹里面搜索classes jar文件 如果有多个classes jar文件 一般
  • SpringData JPA 提示:TransactionRequiredException: Executing an update/delete query

    问题场景 package com zzg dao import javax transaction Transactional import org springframework data jpa repository JpaReposi
  • [MySQL]实训七

    实训目的 设置字段的默认值约束 设置字段的自动增长约束 设置字段的外键约束 有关上述三种约束的概念在上一篇文章中有提及 http t csdn cn 9rV9T 1 在数据库db school中重新定义表tb student 要求以表级完整
  • 4. TypeScript 类

    TypeScript 类 1 TS中定义类 class Pointer x number 实例上的属性必须先声明 y number constructor x number y number args number this x x thi
  • 关于研一Python基础课程第四周课后习题的几点理解(含一个问题的订正)

    1 第八题一个函数的订正 def output prime number for i in range number 1 if is prime i True print i end 这里原文的代码是for i in range numbe
  • VS 配置Qt 开发组件

    VS 配置Qt 步骤比较简单 入门级吧 按照如下几步即可快速配置 希望可以帮到你 一 安装VS Qt组件 1 方法一 扩展 gt 管理扩展 gt 联机 搜素Qt Visual Studio Tools 工具 自动下载完成 按照向导提示正常安
  • 深入解析JS工程逆中的反爬机制

    在当今互联网时代 爬虫技术被广泛应用于数据采集 搜索引擎优化等领域 然而 许多网站为了保护其数据和资源 采取了各种反爬机制 JS逆工程是其中一种常见的反爬手段 通过在网页中利用JavaScript代码动态生成内容 使得爬虫难以获取有效数据
  • ansible批量自动安装LNMP

    转载于 https www cnblogs com hai better p 9995258 html
  • 算法[动态规划]---买卖股票最佳时机

    1 题目 给你一个整数数组 prices 其中 prices i 表示某支股票第 i 天的价格 在每一天 你可以决定是否购买和 或出售股票 你在任何时候最多只能持一股股票 你也可以先购买 然后在同一天出售 返回你能获得的最大利润 2 分析特
  • 蓝桥杯2022 python C组

    蓝桥杯2022 python C组 跟之前的就四题不一样 第二题 特殊时间 就是i 从0 9 j从0 9 i是三个一样的 然后看看他们能不能成为 年 月日 时分 成为年只要大于0就好了 称为月日的话月要从1 12 日呢 特殊的日子就二月28
  • Java连接Oracle数据库(详细!快速上手)

    Java连接Oracle数据库及封装JDBC 如果你点开看到了这篇文章 说明你已经或多或少地通过学校学习亦或是自学了解了 oracle 数据库的基本用法 但是实际在开发程序的时候 我们是不可能手动地去操作sql语句的 而是由程序去调用 这个
  • adb shell 出现 insufficient permissions for device

    新安装了一台电脑 要用adb跟开发板通信 1 安装adb user hp 8200 Desktop factory adb shell The program adb can be found in the following packag
  • 使用过的小巧软件一览

    最近遇到一个脑洞的问题 之前使用Winrar 压缩软件 加密的代码包 由于时间久远 密码忘记了 尝试了记得的各种可能的密码 都是不行 但大概记得长度和部分字符 可就是不记得如何组合的了 后来网上搜索了一番 找到一个小软件 暴力破解了一番 好
  • Linux安全基线检查--centos7

    版权声明 本文为CSDN博主 淡定波007 的原创文章 遵循CC 4 0 BY SA版权协议 转载请附上原文出处链接及本声明 原文链接 https blog csdn net qq 28721869 article details 1146
  • 使用storcli/storcli64工具配置RAID

    storcli storcli工具上传到服务器任意目录 并使用命令chmod x storcli64修改文件权限为可执行 系统下查看Raid卡 root localhost lspci grep LSI 0000 81 00 0 RAID
  • C++函数的定义与使用

    函数的定义和使用 main就是一个函数 它是C 程序的主函数 一个C 程序可以由一个主函数和若干子函数组成 主函数是程序执行的开始点 由主函数调用子函数 子函数还可以再调用其它子函数 调用其它函数的函数称为主调函数 被其他函数调用的函数称为