009_stdc_C语言
回顾:
函数
能完成一个功能的 代码片段
自顶向下
调用,声明,定义
函数的组成
返回值 函数名 (参数)
{
函数体
}
返回值只能返回 一个变量
不能返回一个数组
函数的参数传递机制
值传递
函数的结束
在遇到有return 语句结束
执行到最后一条语句结束
void { if() { exit(0); //结束程序 } else{ } }
递归函数(执行一半的时候发现有调用则进入调用代码)类似包洋葱(一层一层穿进去,又从里面一层一层穿出来)
~~~~~~~~~~~~~~~~
变量的作用域及生命周期
变量的作用域:变量(存储区)能被访问的范围
变量的生命周期:变量的分配,被回收
局部变量(在函数内部声明的变量)的作用域,
C89 局部变量只能在当前函数访问 函数
C99 代码块中局部变量只能在当前代码块访问
同一作用域之内 不能出现同名变量
/* * 局部变量的 作用域 */ #include<stdio.h> int func(); int func() { int a = 3; printf("func a = %d\n",a); return a; } int main(){ int a = 5; int b = 6; printf("func() 返回值=%d\n",func()); printf("main a=%d\n",a); if(a) { //int b = 4; printf("if b = %d\n",b); //4 } printf("b = %d\n",b+1); //7 return 0; }
func a = 3
func() 返回值=3
main a=5
if b = 6
b = 7
局部变量生命周期
auto int a = 0;
局部变量生命周期限于 函数声明该变量开始,函数结束(C99 代码块结束),自动(auto) 变量释放
/*
* 局部变量的生命周期
*/
#include <stdio.h> int func2() { int i = 0; printf("i的地址是%p\n",&i); return 0; } int func1() { int b = 0; int c = 0; func2(); return 0; } int main(){ int a=1; func2(); // i变量的地址 func1(); // i 地址 getchar(); return 0; }
i的地址是00D8FB9C
i的地址是00D8FAB0
全局变量
作用域 当前程序 可访问
生命周期 ,程序开始 到程序结束
#include <stdio.h> int g_i = 0; //如果不初始化 全局变量也是0 int func(); int func2(); //int func2 = 0; //函数名 和全局变量名不能重名 int func2(){ int g_i; g_i=5; return 0; } int func(){ g_i++; return 0; } int main(){ printf("g_i = %d\n",g_i); //0 func(); printf("g_i = %d\n",g_i); //1 func2(); printf("g_i = %d\n",g_i); //1 getchar(); return 0; } g_i = 0 g_i = 1 g_i = 1
在所有函数中可以其进行读写
全局变量名 跟局部变量名可以同名
函数首先会找局部变量(就近原则)
全局变量弊端:
全局命令空间 污染
函数复用降低
静态变量
声明局部变量 前加static 关键字
静态变量的作用域 限定在当前代码块
生命周期 整个程序结束
/* * 静态变量 * 声明局部变量 前加static 关键字 * 静态变量的作用域 限定在当前代码块 * 生命周期 整个程序结束 * */ #include <stdio.h> void func() { static int i = 0; //计数程序调用次数 i++; printf("该函数调用了%d次\n",i); printf("static i 地址%p\n",&i); } int main(){ func(); //1 只对静态局部变量初始化一次 func(); //2 func(); //3 func(); //4 getchar(); return 0; }
该函数调用了1次 static i 地址004D7138 该函数调用了2次 static i 地址004D7138 该函数调用了3次 static i 地址004D7138 该函数调用了4次 static i 地址004D7138
#include <stdio.h> int a=20; int b=30; void swap(){ int sw=0; sw=a; a=b; b=sw; } int main(){ printf("调用之前a=%d b=%d\n",a,b); swap(); printf("调用之后a=%d b=%d",a,b); getchar(); return 0; }
C语言中的数组成分 指针
计算机 对内存的组织管理方式
对内存 访问的基本单元 是8个bit
以8个bit为基本单元,分配一个编号
这个编号就是内存地址,指针
指针变量, 存储地址的变量
整型变量 int i;
声明指针变量
int *p;//声明一个int 型的指针变量p
//p里面存储的地址 指向一个int 型的变量
* 指针
#include <stdio.h> int main(){ int i = 20; printf("i地址是%p\n",&i); //& 取i变量的地址 int *p = &i; //声明一个整形指针变量,存储i变量的地址 printf("p=0x%x\n",p); //将p里面的值进行十六进制输出 getchar(); return 0; }
i地址是012FF9AC
p=0x12ff9ac
* 取指针变量所指向的内存的值
#include <stdio.h> int main(){ int i = 20; printf("i地址是%p\n",&i); //& 取i变量的地址 int *p = &i; //声明一个整形指针变量,存储i变量的地址 //通过指针访问变量i里面的值 printf("i = %d\n",*p); //* 取指针变量所指向的内存的值 getchar(); return 0; } i地址是008FFE9C i = 20
/* * 指针 */ #include <stdio.h> int main(){ int i = 20; int c = 30; int b = 40; printf("i地址是%p\n",&i); //& 取i变量的地址 int *p = &i; //声明一个整形指针变量,存储i变量的地址 printf("p=0x%x\n",p); //将p里面的值进行十六进制输出 //通过指针访问变量i里面的值 printf("i = %d\n",*p); //* 取指针变量所指向的内存的值 //*p 等价于 变量名i //通过指针变量p 修改i的值 c = *p; //c = i; //对i变量的读 printf("c = %d\n",c); //* 取指针变量所指向的内存的值 *p = b; //i = b; //对i变量的写 printf("*p = %d\n",i); //* 取指针变量所指向的内存的值 return 0; }
c = *p; //c = i; //对i变量的读
*p = b; //i = b; //对i变量的写
#include <stdio.h> void swap(int *a,int *b); int main(){ int a=10; int b=20; printf("调用前%d %d\n",a,b); swap(&a,&b); printf("调用后%d %d\n",a,b); getchar(); return 0; } void swap(int *a,int *b){ int d=0; int *c=&d; *c=*a; *a=*b; *b=*c; }
#include <stdio.h> int main(){ char a=10; char *pa = &a; printf("sizeof(pa) = %d\n",sizeof(pa)); long b=10; long *pb = &b; printf("sizeof(pb) = %d\n",sizeof(pb)); getchar(); return 0; } sizeof(pa) = 4 //指针保存的地址编号大小跟系统的位数有关,如32系统的4个字节 sizeof(pb) = 4 //指针保存的地址编号大小跟系统的位数有关,如32系统的4个字节
#include <stdio.h> int main(){ int a[5] = {10,20,30,40,50}; int *pa = a; for(int i = 0;i<5;i++) { printf("*pa+i=%d\n",*pa+i); } getchar(); return 0; }
*pa+i=10
*pa+i=11
*pa+i=12
*pa+i=13
*pa+i=14
拿一个指针变量当数组的方式取下标的方式来使用
#include <stdio.h> int main(){ int a[5] = {10,20,30,40,50}; int *pa = a; for(int i = 0;i<5;i++) { printf("pa[%d] = %d\n",i,pa[i]); } getchar(); return 0; }
pa[0] = 10
pa[1] = 20
pa[2] = 30
pa[3] = 40
pa[4] = 50
数组名就是一个常量指针(首地址) 组数名就是地址
#include <stdio.h> void func(int b[]); void func(int b[]) { for(int i = 0;i<5;i++) { b[i] = i; } } int main(){ int a[5] = {10,20,30,40,50}; func(a); for(int i = 0;i<5;i++) { printf("a[%d] = %d\n",i,a[i]); } getchar(); return 0; }
a[0] = 0
a[1] = 1
a[2] = 2
a[3] = 3
a[4] = 4
#include <stdio.h> void input(int a[],int len){ for (int i=0;i<len;i++) { printf("请输入学生成绩:"); scanf("%d",&(a[i])); } } int max(int a[],int len){ int max =0; for (int i=0;i<len;i++) { if(max>a[i]){ max=max; }else{ max=a[i]; } } return max; } void output (int a[],int len){ printf("学生成绩是:\n"); for (int i=0;i<len;i++) { printf("%d\n",a[i]); } } float avg(int a[],int len){ float avg=0.0; for (int i=0;i<len;i++) { avg+=a[i]; } return avg/len; } int main(){ int a[]={0}; input(a,5); output(a,5); //最高分 printf("max = %d\n",max(a,5)); //平均成绩 printf("avg = %.2f\n",avg(a,5)); getchar(); return 0; }