1.一维整型数组 作为函数形参
形参:
int a[10],int len // int *a, int len
实参:
a len
len = sizeof(a)/sizeof(a[0]); //? 不是
2.一维字符型数组 作为函数形参
形参:
char s[10]; //操作 字符串
实参: s
//注:
字符串有自己结束的标志 '\0'
字符数组
字符串
char s[10] = "hello";
char s[10]
3.二维数组
二维整型数组 作为函数的形参
形式上:
printArray(int a[][4],int row);
形参: 数组形式,行数
实参: 数组名 ,函数
int a[3][4] ;
int a[][4]; //一维数组
//int[] a[]; //
//
printArray(int a[][4],int row);
printArray(int[4] a[],int row);
printArray(int[4] a[],int len);
printArray(int[4] *a,int len); //编译器的处理
//
printArray(int (*a)[4],int len)//编译器最终理解的形式
练习:
找出二维数组中最大值
练习:
计算二维数组边上的和
二维字符型数组:
char s[3][100];
做函数的形参:
形参
数组形式,行数
实参:
数组名, 行数
练习:
给char s[3][100];
实现一个输入功能
练习:
找出字符串中的最大值?
练习:
排序
函数
标识符的作用域 与 可见性问题:
作用域:
起作用的范围
全局作用域:
不在任何一个 {} (花括号)范围内
局部作用域:
一定是某个{} (花括号)范围内
变量:
全局变量
局部变量
可见性问题:
程序代码的角度去看,哪些标识符起作用
标识符的可见性的规则:
1.先定义,后使用
2.同一作用域中,不能有同名标识符
3.在不同的作用域,同名标识符,相互之间没有影响
4.如果是不同的作用域,
但是作用域之间存在嵌套关系,
则,内层的作用域的同名标识符,会屏蔽外层的作用域的同名标识符。
(就近原则)
空间的角度:
全局变量
局部变量
时间角度看:
动态变量
从定义处开始,到作用域结束时,释放
eg:
局部变量
静态变量:
从程序开始执行时,存在,到程序执行结束时,销毁
eg:
全局的变量
静态局部变量 (static)
注意:
全局变量 初始化时 ,必须用常量
静态局部变量(static 修饰的) 初始化时 ,必须用常量
特点:
1. 值 只需要初始化一次
2. 值 具有继承性
变量存储类型:
栈:
局部变量
特点: 自动申请,自动释放
堆:
特点: 手动申请,手动释放
全局区(静态区):
全局变量,静态变量,放在这
特点:
这块区域,是代码编译好之后就确定的。
字符串常量区: (只读)
"hello"
代码区:
放代码 (只读)
程序 = 代码 + 数据
局部变量
静态局部变量
全局变量
int c=20; //全局变量
int main()
{
int a=10; //局部变量
static int b=30;//静态局部变量
}
定义变量:
[存储类型] 数据类型 变量名;
auto //自动变量
//局部变量 -- 栈区
auto int a = 10;
static int a = 10; //静态局部变量 --- 变量就被存储到了 静态区 --- 相当于 延长了生命周期
register int a = 10; //注册 -- 寄存器
// register 表示 建议将该变量放到cpu的寄存器中
for (i = 0; i < 100000000; ++i)
//注意: register 修饰的变量 ,不能作 & 取地址运算
extern int a; //多文件编程中
//声明
//声明变量a,是外部(别的文件)的一个变量,如果要用,请到别的文件寻找
//static
static 修饰全局变量
表示,该全局变量,只能作用域当前文件 (限定作用域为当前文件)
static 修饰函数
表示 该函数 只能作用域当前文件 (限定作用域为当前文件)
static 避免冲突
static 避免数据泄露
static 修饰
变量
局部变量
作用: 延长了生命周期
全局变量
作用: 限定了作用域,只能作用域当前文件
函数
作用,与修饰全局变量类似,只能作用域当前文件
----------------------------------------------------
CPU 内存 硬盘
[ALU + 控制器 + 存储器]
寄存器 //寄居人下
硬盘 ---> 内存 ---> cache ---> CPU的寄存器
i(内存)--->寄存器
|
+1
|
i(内存)<---寄存器
寄存器
|
+1
|
寄存器
总结:
1.函数的思想
2.函数定义
3.函数调用
4.函数原型
5.函数+数组
6.函数作用域 与 可见性
//------------------------
预处理命令:
vi main.c //编辑
gcc main.c ==>a.out //编译
./a.out //运行
#inclue <stdio.h> //#开头预处理名
预处理阶段:
主要将 预处理命令 进行执行,将源程序处理成 不包含预处理命令的 纯的c代码
1. 宏定义
//宏定义的语法
#define 标识符 字符串
作用:
将 字符串 定义为 标识符代表的 宏
#define 宏名 宏值
#define N 10 //符号常量
注意:
1.预处理 本质 做文本的原样替换
2.预处理过程,实际上就是用 宏值 将 出现宏名的地方 进行原样替换 --- 宏的展开
3.做到 ,一改全改 ,方便编程和操作
4.语法
宏名 ---起名字规则 与 变量名规则相同
宏名 ---建议大写
宏定义最后,不要加分号
练习:
求圆的周长的面积
#define PI 3.141516
shift+g //到代码的最后一行
带参宏 //宏函数
#define 宏名(参数) 宏值
注意:
1.只是使用形式上类似函数调用 ,但是本质不同
2.宏展开的副作用
解决:
能加括号的都加上
3.宏的作用域
从定义处开始
到遇到
#undef 宏名
4.宏可以嵌套使用
此时展开过程,
层层展开
5.带参宏
函数
6.宏定义 要求 必须在一行
7.续航符 后面不能有空格
练习:
#define ADD(x) x+x
void main()
{
int m=1,n=2,k=3;
int sum=ADD(m+n)*k; // sum = m+n+m+n*k;
printf("sum=%d", sum);
}
12
10
18
#define MIN(x,y) (x)<(y)?(x):(y)
void main()
{
int i=10, j=15,k;
k=10*MIN(i,j); //k=10*(i)<(j)?(i):(j)
printf(“%d”, k);
}
//100
//15
//
#define PT 5.5
#define S(x) PT*x*x
void main()
{
int a=1,b=2;
printf(“%4.1f”,S(a+b)); // 5.5*a+b*a+b
}
//
9.5
练习:
求圆的周长 和 面积 --- 带参宏
练习:
找两个数的最大值
2. 文件包含
形式:
#include "文件名" //先在当前路径下寻找,找不到,再到系统默认路径下寻找
#include <文件名> //系统的默认路径下去寻找
本质:
文本的原样替换
3. 条件编译
#if 0
#endif
(1)
#ifdef 标识符
程序段1
#else
程序段2
#endif
语义:
如果定义了 标识符
则
编译 程序段1
否则
编译 程序段2
#ifdef 标识符
程序段1
#endif
#ifndef 标识符
程序段1
#else
程序段2
#endif
#if 0
程序段1
#else
程序段2
#endif
有啥用?
1.调试
2.头文件中