1.变量
C语言中的常量有:
1.直接常量1,10.2,’A’等
2.命名常量
使用const关键字定义
使用#define定义
const关键字定义 -常量
const只能在申明时赋值,只能赋值一次;eg:
const int count=10;
int const count1=10;
count=20;//代码出错;
宏定义常量#define
只进行文本替换,不进行计算;eg:
#define Add 10+15
printf("%d\n",10*Add);//=10*10+15
2.枚举定义--enum关键字
enum spectrum{red,orange,yellow,green,blue,indigo,violet};//定义,一般定义在main函数外(spectrum-类型名)//默认情况下,red=0,orange=1,yellow=2...;
也可以指定值 enum spectrum{red=0,orange=10,yellow=20,green=30,blue=40,indigo=50,violet=60};
//也可以指定某些项的值,未指定项参照前一项值加1
enum spectrum{red=0,orange,yellow=20,green,blue=40,indigo,violet=60};
enum spectrum mySpectrum1,mySpectrum2;//定义变量
mySpectrum1 = red; mySpectrum2 = indigo;//赋值
3.函数
C语言中函数分为
-系统库函数-自定义函数
也可以按照有无返回值,或者有无参数分类
库函数
库函数由C系统提供,我们无需编写,直接调用即可使用这些库函数可以完成特定功能
常见库函数
scanf()和printf()
getchar()和putchar()
数学库函数
sqrt(x) :x的平方根
pow(x,y):x的y次幂
abs(x) :x的绝对值
……
自定义函数
定义和声明:
返回类型 函数名称(参数列表);//函数声明
返回类型 函数名称(参数列表){ //函数定义
......
return x;
}
注意:
1.函数声明:自定义函数可以将函数声明写到调用之前,也可以将函数定义写到调用之前
2.回类型为调用函数后所得到的数据的类型,无返回类型为void
3.函数名为程序内唯一,要求符合标识符规范
4.参数列表用于定义函数参数,参数用于传递数据到函数内
5.return语句
如果函数具有返回类型那么return语句所返回的数据类型要一致;
如果为void类型函数,不需要返回内容,但是可以单独使用return用于跳出函数
自定义函数的调用:
int fun1(int x) {
//……
int rst1 = fun1(x); //自我调用
}
void fun2(int x){
//……
int rst1 = fun1(x); //在其他自定义函数中调用
}
int main( ){ //在主函数中调用
int x = 10;
int rst = fun1(x);
//有返回值的自定义函数,调用时必须有同类型的变量接收返回值;
fun2(x);
//无返回值可以直接调用;
}
4.形式参数和实际参数
形参和实参的特点
形式参数简称形参,用于(自定义函数)函数声明及定义时的参数列表中,用于传递数据到函数中形参可以是变量、数组
形参只在函数内部有效。函数调用结束返回主调函数后则不能再使用该形参变量
实际参数简称实参,作为数据的载体,调用函数时用于**数据传递**给函数的形式参数
实参可以是常数、变量、数组元素、表达式、数组
实参可以是常量、变量、表达式、函数等,在进行函数调用时,它们都必须具有确定的值
注意:实参和形参在数量、类型和顺序上应严格一致,否则会发生类型不匹配的错误
实参和形参在传值时的特点
实参在将本身的值传递给形参时复制一份然后交给形参;函数内所操作的形参的值是实参的复制品,所以在函数内改变了形参的值,并不会影响实参的值;
5.变量
变量=全局变量(函数外)+局部变量ps:函数内,当局部变量的命名=全局变量,使用的是局部变量
引用全局变量,必须在定义全局变量之后(下面)
局部变量的作用域范围
1.堆 (例:if里面的单行语句)
2.栈区(例:整个if循环)
3.常量 (例:字符串)
4.代码区 (例:整个函数)
eg.
int n=3;
if(n==3){
int x=9; //栈内有效(栈区变量)
n=9;
}
//x=8; //代码出错,超出x的作用域
printf("n=%d",n);
变量存储类型决定变量存在的时间
局部变量分为三种
auto--自动型变量,不写默认也是自动型,每次使用时被创建,出了其作用域后自动释放
static--静态型变量,定义为静态变量之后,在程序运行期间一直保持,直到程序运行结束
register--寄存器型变量,和自动型变量具有相同的持续时间,但是被存储到了寄存器内,但是有些编译器并不支持此类型,那么就当做auto型使用
全局变量分为三种:
无修饰符(auto)--在程序运行时创建一次,程序结束时销毁,允许在同项目的其他文件中使用该变量
static--程序运行时创建一次,程序结束时销毁,不允许在同项目的其他文件中进行使用
extern--扩展其他文件中的全局变量到本文件进行使用,并不创建新的变量,而是使用已有的同名变量
函数默认为extern,extern可以用来扩展扩展其他文件中的函数到本文件使用
6.函数递归
函数中自己调用自己本身的行为称为递归这种函数称为自引用函数或者递归函数
递归函数如果直接调用自身称为直接递归,如果递归函数调用了另外的函数,而另外的函数调用了递归函数,这种递归方式称为间接递归
eg:
long factorial(int x){
if(x == 1) return 1;
return x * factorial(x – 1);
}
eg. 共N个桃子,猴子每天吃了一半,还不过瘾,就有吃了一个,第二次有将剩下的桃子吃掉一半,有多吃了一个。以后每天都吃了前一天剩下的一半零一个。到了第十天就剩下两个桃子,求第一天多少个
分析: 10 2
9 6
8 14
#include <stdio.h>
int taozi(int x);
int main(int argc, const char * argv[]) {
int a=taozi(1);
printf("%d\n",a);
printf("-------------------------------\n");
return 0;
}
int taozi(int x){
if (x==10) {
return 2;
}
return 2*(taozi(x+1)+1);
}
7.函数式宏定义
函数式宏定义又称带参数宏定义函数式宏定义可以在宏替换时采用类似函数传参数一样的方式进行替换
宏名中包含括号,括号内为参数,但是不需要类型
#define PTF(x) printf(x); //写在include的下面;
预编译时将PTF(“Hi”)替换为printf(“Hi”)。
eg:
#define SQUARE1(x) x*x
#define SQUARE2(x) (x)*(x)
.....
int main(){
//加括号和不加括号的区别
printf("%d\n",SQUARE1(10+20)); //10+20*10+20
printf("%d\n",SQUARE2(10+20));//(10+20)*(10+20)
...
}
经典练习题:
1..编写一个自己的四舍五入函数,并加以使用。把一个实数四舍五入到n位小数的算法是:
将这个数乘以10^n。
将第一步的结果值加0.5。
删除结果的小数部分。
将第三步的结果值除以10^n。
double approach(double number,int n);
int main(int argc, const char * argv[]) {
double num1,num2;
int n;
printf("请输入一个小数\n");
scanf("%lf",&num1);
printf("请输入您想保留的位数\n");
scanf("%d",&n);
num2=approach(num1, n);
printf("%f四舍五入后(保留%d位小数)为%f\n",num1,n,num2);
return 0;
}
double approach(double number,int n){
for (int i=0; i<n; i++) {
number*=10;
}
number+=0.5;
number=(int)number;
for (int j=0; j<n; j++) {
number/=10;
}
return number;
}
2.使用函数(非递归方式)求两个数的最大公约数,欧几里得算法找到最大公约数的步骤如下所示:
1、将较大的数用较小的数相除,保留余数。
2、将较小的数除以余数,再保留余数。
3、继续将前面的余数处以当前的余数,直到余数为0。
4、这时,最后一个非0余数就是最大公约数。
例如,要求84和49的最大公约数,首先84除以49得到余数35,然后49除以35得到余数14,然后35除以14得到余数7,然后14除以7得到余数0,最后的一个非零余数为7,那么84和49 两个数字的最大公约数为7
int getdiv(int a,int b);
int main(int argc, const char * argv[]) {
int num1,num2;
int mindiv=1;
printf("请输入两个整数!(用空格隔开)\n");
scanf("%d%d",&num1,&num2);
mindiv=getdiv(num1, num2);
printf("%d与%d的最大公约数为%d\n",num1,num2,mindiv);
return 0;
}
int getdiv(int a,int b){
int max=a,min=b,remainder=0;
if (a<b) {
max=b;
min=a;
}
do {
remainder=max%min;
if (remainder!=0) {
max=min;
min=remainder;
}
} while (remainder!=0);
return min;
}
3.一块板上有三根针假设为A,B,C。A针上套有4个大小不等的圆盘,大的在下,小的在上。要把这4个圆盘从A针移动C针上,每次只能移动一个圆盘,移动可以借助B针进行。但在任何时候,任何针上的圆盘都必须保持大盘在下,小盘在上。求移动的步骤。
long count=0;
void moves(int n,char fetch,char put);
void hanoi(int n,char a,char b,char c);
int main(int argc, const char * argv[]){
char a='A',b='B',c='C'; //三根珠子的名称
int n = 3; //盘子个数
hanoi(n, a, b, c);
printf("总共移动了%ld次",count);
return 0;
}
void moves(int n,char fetch,char put){
count++;
printf("将第%d个盘子从%c--->%c\n",n,fetch,put);
}
void hanoi(int n,char a,char b,char c){
if(n == 1){
//如果就只有一个盘子,将其从第一个移动到第三个
moves(1,a,c);
}else{
//多于1个盘子的情况,分解为以下三步:
//1、将n - 1个盘子从第一个移动到第二个上
hanoi(n - 1,a,c,b);
//2、将第n个盘子从第一个移动到第三个上
moves(n,a,c);
//3、将n - 1个盘子从第二个上移动到第三个上
hanoi(n - 1,b,a,c);
}
}
随堂笔记为个人学习笔记,若有错误,望指出,谢谢!!