函数
基本语法格式:
返回类型 函数名称(参数类型 参数){
函数主体
}
全局变量和局部变量
全局变量
指在定义之后的所有程序段内都有效的变量(即定义在所有函数之前)
#include<stdio.h>
int x;
void change(){
x=x+1;
}
int main(){
x=10;
change();
printf("%d\n",x);
return 0;
}
输出结果:
11
局部变量
与全局变量相对,局部变量定义在函数内部,且只在函数内部生效,函数结束时局部变量销毁,示例如下:
#include<stdio.h>
void change(int x){
x=x+1;
}
int main(){
int x=10;
change(x);
printf("%d\n",x);
return 0;
}
输出结果:
10
函数定义的小括号内的参数称为形式参数或者形参,而把实际调用时小括号内的参数称为实际参数或实参。
#include<stdio.h>
int MAX(int a, int b,int c){
int M;
if(a>=b && a>=c) M=a;
else if(b>=a && b>=c ) M=b;
else M=c;
return M;
}
int main(){
int a,b,c;
scanf("%d %d %d",&a,&b,&c);
printf("%d\n",MAX(a,b,c));
return 0;
}
输入输出:
3 4 5
5
主函数对于一个程序来说只能有一个,以函数的眼光来看:main是函数名称,小括号内没有填写东西,因此是无参函数;返回类型是int型,并且在函数主体的最后面返回了0.对计算机来说,main函数返回0的意义在于告知系统程序正常终止。
以数组作为函数参数
数组作为函数的参数时,参数中数组的第一维不需要填写长度(如果是二维数组,那么第二维需要填写长度),实际调用时也只需填写数组名。最重要的是,数组作为参数时,在函数中对数组元素的修改就等同于是对原数组元素的修改(这与普通的局部变量不同)。
#include<stdio.h>
void change(int a[],int b[][5]){
a[0]=1;
a[1]=3;
a[2]=5;
b[0][0]=1;
}
int main(){
int a[3]={0};
int b[5][5]={0};
change(a,b);
for (int i=0;i<3;i++){
printf("%d\n",a[i]);
}
return 0;
}
输出:
1
3
5
虽然数组可以作为参数,但是不允许作为返回类型出现。如果想要返回数组,则只能用上面的方法,将想要返回的数组作为参数传入。
函数的嵌套调用
函数的递归调用
指针
在C语言中用指针来表示内存地址,而如果这个内存地址恰好是某个变量的地址,那么又称“这个指针指向该变量”。
怎样获得变量的地址?
需要用到取地址运算符&,只要在变量前面加上&,就表示变量的地址。
例如。一个定义为int a 的变量,&a就表示它的地址。
#include<stdio.h>
int main(){
int a=1;
printf("%d, %d",&a,a);
return 0;
}
输出结果:
6422044, 1
指针变量
指针变量用来存放指针(或者可以理解成地址),这个关系就跟int型变量用来存放int型常量相同。指针变量的定义,在某种数据类型后加星号*来表示这是一个指针变量,例如:
int * p;
double *p;
char * p;
int *p1, p2;
只有p1是int*的,p2是int型的。
int *p1, *p2, *p3;
上面均为指针变量。
给指针变量赋值的方式一般是把变量的地址取出来,然后赋给对应类型的指针变量:
int a;
int *p = &a;
上面的代码也可以写为:
int a;
int* p;
p = &a;
int*是指针变量的类型,而后面的p才是变量名,用来存储地址,因此地址&a是赋给p而不是 *p。
int *p = &a;
指针变量p存放a的地址,为了通过p来获得变量a,可以把星号* 视为一把开启房间的钥匙,将其加在p的前面,这样 *p就可以把房间打开,然后获得变量a的值。
#include<stdio.h>
int main(){
int a;
int* p=&a;
a=233;
printf("%d\n",*p);
return 0;
}
输出:
233
对一个int* 指针型变量p来说,p+1是指p所指的int型变量的下一个int型变量地址。
指针变量支持自增和自减操作,因此p++等同于p=p+1使用。
int* p 定义的指针变量p不能够存放double型或char型数据的地址,而必须是int型数据的地址。
指针与数组
数组名称也作为数组的首地址使用 ,例如a==&a[0]
#include<stdio.h>
int main(){
int a[10]={1};
int* p=a;
printf("%d\n",*p);
return 0;
}
输出
1
使用指针变量作为函数参数
这时把变量的地址传入函数,如果在函数中对这个地址中的元素进行改变,原先的数据就会切实地被改变。
#include<stdio.h>
void change(int* p){
*p=233;
}
int main(){
int a=1;
int* p =&a;
change(p);
printf("%d\n",a);
return 0;
}
输出
233
在上述代码中,把int*型的指针变量p赋为a的地址,然后通过change函数把指针变量p作为参数传入。此时传入的其实是a的地址,在change函数中,使用 * p修改地址中存放的数据,也就改变了a本身。最后输出a时,就已经改变了值,这种传递方式被成为地址传递。
引用
#include<stdio.h>
void change(int &x){
x=1;
}
int main(){
int x=10;
change(x);
printf("%d\n",x);
return 0;
}
输出
1
结构体的使用
结构体的定义
struct Name{
//一些基本的数据结构或者自定义的数据类型
};
例如
struct studentInfo{
int id;
char gender;//'F'or 'M'
char name[20];
char major[20];
} Alice, Bob, stu[1000];
struct studentInfo{
int id;
char name[20];
studentInfo* next;
}stu, *p;
访问stu中变量的写法:
stu.id
stu.name
stu.next
访问指针变量p中元素的写法如下:
(*p).id
(*p).name
(*p).next
单点测试与多点测试
多点测试与单点测试相对,多点测试要求程序能够一次运行所有的数据,并要求所有输出结果都必须完全正确,才能算作这题通过。
三种输入方式
(1)while…EOF型
while (scanf("%d",&n)!=EOF){
...
}
当在黑框输入数据时,并不会触发EOF(End Of File 在C语言中代表-1).如果想在黑框中手动触发EOF,可以按<Ctrl+Z>组合键,这时就会显示一个^Z,按键就可以结束while了。
(2) while…break型
在while…EOF的内部进行判断,当满足退出条件时中断break当前while循环。
(3) while(T- -)型
在这种类型中,题目会给出测试数据的组数,然后才给出相应数量组数的输入数据。
由于给定了测试数据的组数,因此需要一个变量T来存储。