函数概念:实现某种功能的一个模块(——子程序),可重复使用C语言讲究模块化开发,类似拼装)
函数类型:
一.库函数:
使用时引入头文件
函数要点:头文件,功能,函数名,参数列表(个数和类型),返回值和返回值类型
学习链接:C语言常用库函数大全 - C语言网 (dotcpp.com)
二.自定义函数:
***自定义函数***
ret_type fun_name(para1,*) 函数名与功能相关联性极强使用小驼峰式命名法或中间下划线法
{
statement; // 函数体 如果有返回值,在函数体内使用return
}
ret_type 返回类型 由所需数据类型决定(如果没有返回值:void)
fun_name 函数名
para1 函数参数
一个函数只能返回一种类型的数据 函数:传几个接几个
定义函数不能嵌套,但是能够嵌套调用(例如在这个定义的函数中调用另一个定义好的)
函数 {最好一个函数控制一种功能}
(1)变量:
- 全局变量 :未初始化默认值是零
- 局部变量 :未初始化是个随机值在{}包裹中的区域中定义并使用
- 主要区别是作用于的范围不同(scope)
- 静态变量:static修饰局部变量函数前加静态函数改变函数链接属性
#include <stdio.h>
void show()
{
static int a = 1;
a++;
printf("%d\n",a);
}
int main()
{ int i = 0;
while (i<4)
{
show();
i++;
}
return 0;
}
、
const作用是让变量具有常属性,不能修改
形参是实参的临时拷贝,形参的改变不会影响到实参(函数执行完了以后就会被销毁)
数组作为函数的参数使得形参的改变影响到形参
const关键字:
1,修饰普通变量
#include <stdio.h>
int main(){
const float pi = 3.14;
pi=3.1415;
return 0;
}
2,修饰指针变量:
- int const *p; //指针p本身的值可以改,但是p所指向的内容不能改.(*p不能改)
- const int *p; //指针p本身的值可以改,但是p所指向的内容不能改.(*p不能改)
- int *const p; //指针p本身的值不能改,但是p所指向的内容可以改.(p不能改)
- int const * const p; //指针p本身的值不能改,并且p所指向的内容也不能改.(p和*p都不能改)
- const int* const p; //指针p本身的值不能改,并且p所指向的内容不能改.(p和*p都不能改)
3,常量指针:
说的是不能通过这个指针改变变量的值
const int *j = &i;const 后面修饰int*,表示不能通过指针改变变量的值.
4,指针常量 :
说明指针本身是个常量,指针中存储的地址不能更改
int * const j = &i;const 后面修饰的为j,表示指针中存储的地址不能更改
#include <stdio.h>
int main()
{
int data = 100;
int const *x = &data;
const int *y = &data;
int* const z = &data;
int const *const p = &data;
const int *const q = &data;
x++;
(*x)++; //错误
y++;
(*y)++; //错误
z++; //错误
(*z)++;
p++; //错误
(*p)++; //错误
q++; //错误
(*q)++; //错误
return 0;
}
交换量数字:说明指针本身是个常量,指针中存储的地址不能更改
#include <stdio.h>
void swap(int x, int y)
{
printf("before:a = %d, b = %d\n", x, y);
int temp = 0;
temp = x;
x = y;
y = temp;
printf("after:a = %d, b = %d\n", x, y);
}
/*2号void swap(int* x, int* y)
{
printf("before:*a = %d, *b = %d\n",*x,*y);
int temp = 0;
temp = *x;
*x = *y;
*y = temp;
printf("after:*a = %d, *b = %d\n", *x,*y);
}*/
int main()
{
int a = 0, b = 0;
scanf("%d %d", &a, &b);
// 交换两个变量
printf("before:a = %d, b = %d\n", a, b);
swap(a, b); // 传值调用
//2号swap(&a, &b);
printf("after:a = %d, b = %d\n", a, b);
return 0;
}
2 结果:传地址可以通过改变形参从而改变实参,*x *y将原本保存地址的指针解引用直接访问地址影响到数值
使用指针传的好处:
- 节约空间,毕竟只需要开辟八个空间
- 可以返回多个值
#include <stdio.h>
void max_min(int a,int b,int* x, int* y){
if(a>b){
*x = a;
*y = b;
} else{
*x = b;
*y = a;
}
}
int main()
{
int a,b,x,y;//a为max,b为min
scanf("%d %d", &a, &b);
max_min(a,b,&x,&y);通过修改形参来达到修改实参的目的
printf("after:a = %d, b = %d\n",x, y);
return 0;
}
(2)函数的调用:
1.嵌套调用:在主体中调用另一函数
eg:冒泡排序
#include <stdio.h>
void bubble(int *,int );
void print_p(int *,int );
int main()
{
int b [4]={0};
int size = sizeof(b)/sizeof(b[0]);
for (int i=0;i<size;i++)
{
scanf("%d", &b[i]);
}
bubble(b,size);
putchar('\n');
print_p(b,size);
return 0;
}
//冒泡排序从大到小排序
void bubble(int* b,int size)函数传数组地址和长度
{
if(size==0)
{ return;}
//外层控制轮数
for (int i = 1; i < size; i++){
for (int j = 0; j < size-i; j++) {
if(*(b+j)>*(b+j+1)){
*(b+j) = *(b+j+1)^*(b+j);
*(b+j+1) = *(b+j+1)^*(b+j);
*(b+j) = *(b+j+1)^*(b+j);
}
}
}
}
void print_p(int* b,int size){
for (int i = 0; i < size; i++) {
printf("%-3d",*(b+i));
}
putchar('\n');
}
2.链式调用:函数一个函数的返回值可以作为领一个数的返回值
eg:比较大小
#include <stdio.h>
int getMax(int a,int b)
{
return a>b?a:b;
}
int main()
{
int q=34,e=24,w=25;
//int l = getMax(q,e);
//int y = getMax(l,w);
//printf("%d",y);
int u = getMax(getMax(q,e),w);
printf("%d",u);
return 0;
}
3.函数的声明 :
创建:头文件文件名+.h 把需要调用的库函数放入头文件中
使用:#include“文件名.h”
使用ifndef用来防止头文件的重复使用从而减小占用内存的大小:
#ifndef __文件名(大写)_h__(这是两个下划线)
#define __文件名(大写)_h__
//头文件2
#endif
- 进行模块化开发时先创建Add.h放入头文件
- Add.c放入main函数主体
- 最后将自己创建的函数放入.c文件中
Linux中的分屏操作:
- vsp左右分屏
- sp上下分屏
- wqall保存所有的修改
- Ctrl+w切换窗口