网站人员队伍建设落后云南网站建设百度
- 函数间的值传递与地址传递
值传递方式:指主调函数把实参的值赋给形参。
在这种传递方式下,主调函数中的实参地址与被调函数中的形参地址是相互独立的。
函数被调用时,系统为形参变量分配内存单元,并将实参的值存入到对应形参的内存单元中。
被调函数在执行中使用的是形参,形参的变化和实参无关,被调函数return时,系统自动收回为形参分配的内存空间。
#include<stdio.h>void main(){void s(int);int n;printf("input number\n");scanf("%d",&n);//输入10s(n);//调用函数输出55printf("n=%d\n",n);//主函数依旧输出10
}void s(int n){int i;for(i=n-1;i>=1;i--)n+=i;printf("ns=%d\n",n);
}
地址传递方式:指将存放实参的地址传递给形参。
在这种传递方式下,被调用函数在执行中当需要存取形参值时,是通过形参来找到实参所在地址后,直接存取实参地址中的数据。在这种传递方式下,如果被调函数改变了形参的值,也就改变了主调函数中实参的值。被调函数执行完返回主调函数时,被调函数形参的新值也就通过实参的地址传回主调函数。
此外,无论是值传递还是地址传递都只能实现数据的单向传递,在调用时只能将实参值传递给形参。
#include<stdio.h>void main(){void s(int*);int n;printf("input number\n");scanf("%d",&n);//输入10s(&n);//调用函数输出10printf("n=%d\n",n);//主函数依旧输出10
}void s(int *n){int *p=n,ns=0;for(;*p>=1;p--)ns+=*p;printf("ns=%d\n",ns);
}
- 局部变量与全局变量
局部变量:也称为内部变量,是在函数内定义的变量。作用域仅限于函数内。
注意点:形参变量是属于被调函数的局部变量,实参变量是属于主调函数的局部变量。
允许在不同的函数中使用相同的变量名,它们代表不同的对象,分配不同的单元,互不干扰。
在复合语句里定义的局部变量作用域只在复合语句范围内。
全局变量:也称为外部变量是在函数外部定义的变量。作用域从定义位置开始到本程序文件的末尾。
注意点:同一个源文件中,全局变量与局部变量同名,则在局部变量的作用范围内全局变量被屏蔽。
使用全局变量可实现各函数之间的数据传递,但并不提倡,会降低程序的可读性并且浪费存储空间。
静态局部变量和静态全局变量的区别:
静态局部变量:它的数据存储在静态存储区,它与局部变量的区别在于函数退出时变量始终存在,但不能被其他函数使用,当再次进入该函数时,将保持存上次的结果,其他与局部变量一样。
静态全局变量:只在定义它的源文件中可见,而在其他源文件中不可见的变量,它与全局变量的区别是全局变量可以再说明为外部变量(extern),被其他源文件使用,而静态全局变量却不能再被说明为外部的,只能被所在的源文件使用。 - 函数的递归调用:在一个函数体内直接或间接调用它自身的操作。
为防止递归调用无终止的进行,必须在函数体内有终止递归的手段。采用办法是加条件判断,满足某种条件后就不再做递归调用,然后逐层返回。
区别于函数的嵌套调用:其指允许在一个函数的定义中出现对另一个函数的调用。
用递归法计算n!:
#include<stdio.h>long fun(int n){long f;if(n==0||n==1)f = 1;elsef=fun(n-1)*n;return f;
}void main(){int n;long y;printf("input a number:\n");scanf("%d",&n);y = fun(n);printf("%d!=%ld",n,y);
}
import java.util.*;
public class one {public static long fun(int n){long f;if(n==0||n==1)f = 1;elsef=fun(n-1)*n;return f;}public static void main(String[] args){int n;long y;System.out.println("input a number:");Scanner sc=new Scanner(System.in);n=sc.nextInt();y = fun(n);System.out.println(n+"!="+y);}
}
def func(count):if count == 1:return 1else:return func(count-1)*count
num = int(input("请输入一个数:"))
print("%d的阶乘为%d"%(num,func(num)))
python里面的%()表示字符串格式化操作,常用的操作有%s %d %r等。是指将其他变量置入字符串特定位置以生成新字符串的操作,比如:
n = "Aki"
"My name is %s" % n
这段代码首先定义了一个名为n的变量,内容为Aki。然后下方的字符串中有一个%s,他的含义是“这里将被替换成一个新的字符串”,用作替换的内容放在字符串后面的%后面,就是那个n。所以最终这个字符串会变成My name is Aki。字符串中的%后面会附带一个字母,代表着用来替换的变量的类型,比如说%d代表着你将替换到此处的变量是一个整数,而%s代表着一个字符串。
另外,这种操作可以同时将多个变量放进字符串,只需要用括号把变量们括起来。
>>> "www.%s.com"%"zhihu" #字符串
'www.zhihu.com'>>> "%dkm"%1990 #整数型
'1990km'>>> "%s %d %f"%("abc",123,3.21) #多个值
'abc 123 3.210000'
说明如下:
%[(name)][flags][width].[precision]typecode
(name) 为命名
flags 可以有+,-,' '或0。
+表示右对齐。-表示左对齐。0表示使用0填充。
' '为一个空格,表示在正数的左侧填充一个空格,从而与负数对齐。
width 表示显示宽度
precision 表示小数点后精度
typecode 为类型码
%s 字符串 (采用str()的显示)
%r 字符串 (采用repr()的显示)
%c 单个字符
%b 二进制整数
%d 十进制整数
%i 十进制整数
%o 八进制整数
%x 十六进制整数
%e 指数 (基底写为e)
%E 指数 (基底写为E)
%f 浮点数
%F 浮点数,与上相同
%g 指数(e)或浮点数 (根据显示长度)
%G 指数(E)或浮点数 (根据显示长度)
%% 字符"%"
>>> print("%6.3f" % 2.3)2.300
# 第一个"%"后面的内容为显示的格式说明,6为显示宽度,3为小数点位数,f为浮点数类型
# 第二个"%"后面为显示的内容来源,输出结果右对齐,2.300长度为5,故前面有一空格
>>> print("%+10x" % 10)+a
# x为表示16进制,显示宽度为10,前面有8个空格
>>>print("%-5x" % -10)
-a
# "%-5x" 负号为左对齐,显示宽度为5,故-a后面有3个空格
>>>pi=3.1415
>>>print ("pi的值是%s"%pi)
pi的值是3.1415
>>>print ("pi的值是%.8f"%pi)
pi的值是3.14150000
- Hanoi塔问题
#include<stdio.h>void move(int n,char x,char y,char z){if(n==1)printf("%c-->%c\n",x,z);else{move(n-1,x,z,y);printf("%c-->%c\n",x,z);move(n-1,y,x,z);}
}void main(){int h;printf("input a number:");scanf("%d",&h);printf("the step to moving %2d diskes:\n",h);move(h,'a','b','c');
}
import java.util.*;
public class one {public static void move(int n,char x,char y,char z){if(n==1)System.out.println(x+"-->"+z);else{move(n-1,x,z,y);System.out.println(x+"-->"+z);move(n-1,y,x,z);}}public static void main(String[] args){int h;System.out.println("input a number:");Scanner sc=new Scanner(System.in);h=sc.nextInt();System.out.println("the step to moving "+h+" diskes:3");move(h,'a','b','c');}
}
def move(n,x,y,z):if n == 1:print(x,"-->",z)else:move(n-1,x,z,y)print(x,"-->",z)move(n - 1, y, x, z)
h=int(input("请输入一个数:"))
print("the step to moving %2d diskes:\n",h)
move(h,'a','b','c')
- 输入n值,输出高度为n的等边三角形。(递归实现)
#include<stdio.h>void prt(char c,int n){if(n>0){printf("%c",c);prt(c,n-1);}
}
void main(){int i,n;scanf("%d",&n);for(i=1;i<=n;i++){prt(' ',n-i);prt('*',2*i-1);printf("\n");}
}
- 斐波那契序列(Fibonacci数列):
斐波那契数列(Fibonacci sequence),又称“黄金分割”数列。
比如这样一个数列:1,1,2,3,5,8,13,21,34,55,89… …数列从第3项开始,每一项都等于前两项之和。在C语言中,我们可以用多种方式来实现斐波那契数列。这里针对以下三种方式来体现每种方法的效率:1)递归,2)非递归,3)数组。
- 递归。该递归属于多分支递归,会造成栈溢出。
//递归#include<stdio.h>int Fib(int n){if(n==1||n==2)//数列前两项{return 1;}else//从第三项开始{return Fib(n - 1) + Fib(n - 2);}return 0;}int main(){int n = 0;scanf("%d", &n);//输入一个数int ret = Fib(n);//计算斐波那契数列printf("%d\n", ret);//打印结果return 0;}
2)非递归。非递归较递归效率更高,避免了重复计算的时间和空间。
//非递归
#include<stdio.h>int Fib(int n)
{int num1 = 1;int num2 = 1;int tmp = 1;while (n>2){tmp = num1 + num2;num1 = num2;num2 = tmp;n--;}return tmp;
}
int main()
{int n = 0;int ret = 0;scanf("%d", &n);ret = Fib(n);printf("该数的斐波那契数列为%d", ret);return 0;
}
3)数组。
//数组法
#include<stdio.h>int Fib(int n)
{int i;int arr[100] = {0,1,1};for (i = 2; i <= n; i++)//从第一项开始{arr[i] = arr[i - 1] + arr[i - 2]; }return arr[n];
}
int main()
{int n;scanf("%d", &n);printf("%d", Fib(n));return 0;
}
import java.util.*;
public class one {public static int Fib(int n){if (n == 1|| n==2)return 1;elsereturn Fib(n-1)+Fib(n-2);}public static void main(String[] args){int n,ret;System.out.println("input a number:");Scanner sc=new Scanner(System.in);n=sc.nextInt();ret=Fib(n);System.out.println(ret);}
}
def Fib(n):if n == 1 or n==2:return 1else:return Fib(n-1)+Fib(n-2)return 0
n = int(input("请输入一个数:"))
ret = Fib(n)
print(ret)
- 静态存储变量和动态存储变量:
静态存储变量通常是在变量定义时就分定存储单元并一直保持不变, 直至整个程序结束。
动态存储变量是在程序执行过程中,使用它时才分配存储单元, 使用完毕立即释放。 典型的例子是函数的形式参数,在函数定义时并不给形参分配存储单元,只是在函数被调用时,才予以分配, 调用函数完毕立即释放。如果一个函数被多次调用,则反复地分配、 释放形参变量的存储单元。所以我们可知,静态存储变量是一直存在的, 而动态存储变量则时而存在时而消失的。
1)静态存储变量通常是在变量定义时就分定存储单元并一直保持不变,直至整个程序结束。静态变量,全局动态变量都是静态存储变量。
2)动态存储变量是在程序执行过程中,使用它时才分配存储单元,使用完毕立即释放。
3)静态存储变量是一直存在的,而动态存储变量则时而存在时而消失。
通常把由于变量存储方式不同而产生的特性称为变量的生存期。
4)静态存储只会初始化一次。
区分:定义或者声明变量时,没有static修饰符的就是动态变量,有static修饰符的就是静态变量。 - 输入以秒为单位的一个时间值,将其转化成“时:分:秒”的形式输出。将转换工作定义成函数。
#include<stdio.h>void fun(int sec){int h,m,s;h = sec/3600;m = sec/60-60*h;s = sec-h*3600-m*60;printf("%d:%d:%d\n",h,m,s);
}
void main(){int sec;scanf("%d",&sec);fun(sec);
}
- 编写一个递归函数将一个整数n转换成相应的字符串。
#include<stdio.h>void fun(int n){int i,j;i = n%10;j = n/10;if(j) fun(j);printf("%c",i+'0');
}
void main(){int n;printf("Please input an integer: ");scanf("%d",&n);printf("Switch to string: ");fun(n);printf("\n");
}
c 语言 int 转字符串,C++ 字符串string和整数int的互相转化操作:
一、string转int的方式
1、采用最原始的string, 然后按照十进制的特点进行算术运算得到int,但是这种方式太麻烦,这里不介绍了。
2、采用标准库中atoi函数。
string s = "12";
int a = atoi(s.c_str());
对于其他类型也都有相应的标准库函数,比如浮点型atof(),long型atol()等等。
3、采用sstream头文件中定义的字符串流对象来实现转换。
istringstream is("12"); //构造输入字符串流,流的内容初始化为“12”的字符串
int i;
is >> i; //从is流中读入一个int整数存入i中
二、int转string的方式
1、采用标准库中的to_string函数。
int i = 12;
cout << std::to_string(i) << endl;
不需要包含任何头文件,应该是在utility中,但无需包含,直接使用,还定义任何其他内置类型转为string的重载函数,很方便。
2、采用sstream中定义的字符串流对象来实现。
ostringstream os; //构造一个输出字符串流,流内容为空
int i = 12;
os << i; //向输出字符串流中输出int整数i的内容
cout << os.str() << endl; //利用字符串流的str函数获取流中的内容
字符串流对象的str函数对于istringstream和ostringstream都适用,都可以获取流中的内容。
补充知识:C++ 将整数、浮点数转为字符串
前言:
用 sprintf可以把整数、浮点数转为字符串。
1、整数
#include<iostream>
#include<stdio.h>
using namespace std;void main() {int n=12345;//待转整数char s[10];//转换后的字符串sprintf(s,"%d", n);cout<<s<<endl;
}
2、浮点数
#include<iostream>
#include<stdio.h>
using namespace std;void main() {float n = 12345.67;//待转整数char s[10];//转换后的字符串sprintf(s,"%.2f", n);cout<<s<<endl;
}
import java.util.*;
public class one {public static void main(String args[]) {int a = 10;int b = 20;//variable to store resultString result = null;//converting integer to stringresult = Integer.toString(a);//句法:Integer.toString(int);System.out.println("result (value of a as string) = " + result);result = Integer.toString(b);System.out.println("result (value of b as string) = " + result);}
}
intVal = 12345
result = str(intVal)
print(type(intVal))
print(type(result))
print(intVal,result)
- 预处理命令并不是C语言本身的组成部分。
- 带参数的宏与函数有什么区别?
(1)宏展开仅仅是字符串的替换,不会对表达式进行计算;
(2)宏在编译之前就被处理掉了,它没有机会参与编译,也不会占用内存,而函数是一段可以重复使用的代码,会被编译,会给它分配内存,每次调用函数,就是执行这块内存中的代码。
#include<stdio.h>
#define MAX(a,b,c) (a>b?a:b)>c?(a>b?a:b):c
float max(float a,float b,float c){if(a<b) a = b;if(a<c) a = c;return a;
}
int main(){float x,y,z;scanf("%f %f %f",&x,&y,&z);printf("%.3f\n",MAX(x,y,z));printf("%.3f\n",max(x,y,z));return 0;
}
-
const与define的区别:
1、define是预编译指令,const是普通变量的定义,define定义的宏是在预处理阶段展开的,而const定义的只读变量是在编译运行阶段使用的。
2、const定义的是变量,而define定义的是常量。define定义的宏在编译后就不存在了,它不占用内存,因为它不是变量,系统只会给变量分配内存。但const定义的常变量本质上仍然是一个变量,具有变量的基本属性,有类型、占用存储单元。可以说,常变量是有名字的不变量,而常量是没有名字的。有名字就便于在程序中被引用,所以从使用的角度看,除了不能作为数组的长度,用const定义的常变量具有宏的优点,而且使用更方便。所以编程时在使用const和define都可以的情况下尽量使用常变量来取代宏。
3、const定义的是变量,而宏定义的是常量,所以const定义的对象有数据类型,而宏定义的对象没有数据类型。所以编译器可以对前者进行类型安全检查,而对后者只是机械地进行字符替换,没有类型安全检查。这样就很容易出问题,即“边际问题”或者说是“括号问题”。 -
typedefine 和 define 的区别?
检查不同:#define仅仅是在编译前期的预处理过程中进行源代码中的字符串替换,不参与之后的翻译期语法检查。而typedef定义的类型别名会被静态类型系统检查,如果发现了用未定义的类型来定义新的类型,会明确地产生编译错误。
用法不同:typedef 用来定义一种数据类型的别名,增强程序的可读性。define 主要用来定义常量,以及书写复杂使用频繁的宏。
执行时间不同:typedef 是编译过程的一部分,有类型检查的功能。define 是宏定义,是预编译的部分,其发生在编译之前,只是简单的进行字符串的替换,不进行类型的检查。
作用域不同:typedef 有作用域限定。define 不受作用域约束只要是在define 声明后的引用都是正确的。
对指针的操作不同:typedef 和define 定义的指针时有很大的区别。
注意:typedef 定义是语句,因为句尾要加上分号。而define 不是语句,千万不能在句尾加分号。 -
函数的原型声明一般在函数的调用之前,而函数的定义可以在函数调用之后。
-
函数的参数包括形式参数和实际参数,形式参数只能是变量,而实际参数可以是变量、常量和表达式。函数在调用时,实际参数的个数、类型和顺序参数保持一致。
-
函数的返回值大小由return后面的表达式的值决定,返回值的类型由函数定义时的类型决定。
-
当函数调用时,系统给形式参数分配存储空间,并把实际参数的值复制给形式参数,调用结束后形式参数所占用的内存被释放。
-
在C语言中,不能在一个函数内定义另外的函数。
-
C语言中的宏定义,其本质就是用一个不带引号的字符串替换宏名。