大程序划分为若干个程序模块,每个模块实现一个特定的功能,这些模块称为子程序,c语言中子程序用函数实现
.exe文件 在磁盘存放
程序执行中就会创建一个进程(程序的一次执行),计算机会给进程分配cpu与内存空间(用户空间)
作用域(可见性) 此阶段针对于编译与链接过程
作用域: 标识符能够被使用的范围; 只有在作用域内标识符才可以被使用
- 函数中定义的标识符,包括形参和函数体中定义的局部变量,作用域都在该函数内(函数域)
- 文件作用域也称全局作用域,定义在所有函数之外的标识符,具有文件作用域,作用域为从定义处到整个源文件结束.文件中定义的全局变量和函数都具有文件作用域.
生存期(生命期) 此阶段程序的执行过程(必须是成功编译链接并生成了可执行文件)
生命期: 标识符从程序开始运行时被创建,具有存储空间,到程序运行结束时消亡,释放存储空间的时间段.
- 局部变量与形参生存期: 函数被调用,分配存储空间,到函数执行结束,存储空间释放 存放在.stack区
- 全局变量的生存期: 从程序执行前开始,到执行后结束,存放在.data区
全局变量存放在 .data区
在栈区中,遇到函数会为其参数分配栈帧,函数结束栈帧也会被回收给系统
根据g_mid作用域 编译不会通过 未编译链接成功 不会生成可执行文件
运算符
逗号运算符的优先级最低
%(余数)取模 是只针对整型的运算符 char; short; int; long int; long long
取模应用:
判断是否能够整除这个数
判别奇偶数 质数 (辗转相除)
计算范围 形成循环
*= +=
int a = 3, b = 4, c = 5;
a *= b + 5; // a = a * (b + 5) == 27
printf("a = %d \n", a);
三目运算符 ? :
max = a > b ? a : b // max为ab中最大的值 a>b为真 取:左面的值
前置++ 后置++
具有回写能力
int a = 10, b = 10;
int x = 0;
x = ++a;
printf("x = %d a = %d \n"); // 11 11
x = b++;
printf("x = %d b = %d \n"); // 10 11
x = ++a | x = b++ |
---|---|
取值 a 放入临时量 tmp | 取 b 的值赋值给 x |
tmp 自增 1 | 取 b 放入临时量 tmp |
tmp 回写到 a | tmp自增1 |
a 赋值到 x | tmp 回写到 b |
指针
内存(程序中成为主存DRAM)是计算机中重要的部件之一,是外存(磁盘)与cpu进行沟通的桥梁.
计算机中所有程序的运行都是在内存中进行,为了有效的使用内存,就把内存以8位二进制(bit)划分为存储单元(1字节).为了有效的访问到内存的每个存储单元,就给内存存储单元进行了编号,这些编号被成为该内存存储单元的地址.
x86 32位系统 32个地址线 32个二进制位 4字节存储地址编号 编址范围2^32=4G 低地址0 高地址F
x64 64位系统
指针变量是存储地址的变量 32位系统中指针占4字节 64位系统中指针占8字节
int a = 10;
int* p; // *声明p是指针变量
p = &a;
int *p = &a;
*p; // *取值
&p => p自身的地址
p => 存储内容的地址
*p => a; // a => 10
变量取低地址作为变量的首地址
计算机存储数据时是小端存储 高位数存在高地址 低位数存在低地址
结构体 一种数据类型(程序开发者自己设计的类型) struct(关键字) Student(类型名)
struct Student
{
char s_id[20];
char s_name[20];
char s_sex[10];
int s_age;
}Stud; // Stud为全局结构体变量
int main()
{
int a = 10;
struct Student stud = { "220987","hi","man",21}; // stud为结构体变量
struct Student* sp = &stud; // sizeof(sp) = 4
// sp => &stud;
// *sp = stud;
(*sp).s_id;
sp->s_id;
printf("id: %s \n", atud.s_id);
return 0;
}
文件
标准文件
通常显示器为标准输出文件 printf 向这个文件输出数据 putchar
通常键盘为标准输入文件 scanf 向这个文件输入数据 getchar(从缓冲区中读数据)
文件 | 硬件设备 |
stdin | 标准输入文件,一般指键盘scanf()、getchar()等函数默认从stdin获取输入 |
stdout | 标准输出文件,一般指显示器printf()、putchar()等函数默认向stdout输出数据 |
stderr | 标准错误文件,一般指显示器perror()等函数默认向stderr输出数据 |
stdprn | 标准打印文件,一般指打印机 |
缓冲区
程序执行时,所提供的一块存储空间(在内存中),可用来暂时存放做执行的数据. 缓冲区的设置为了提高存取效率,因为内存的存取速度比磁盘驱动器快很多.
char ch = '\0';
scanf("%c",&ch);
ch = getchar();
关键字(保留字) 是已被c语言本身使用,不能作其他用途使用的字
sizeof 计算类型大小或变量大小(字节个数) 编译时就确定了大小 返回值是无符号整型 unsigned int (void不可以计算) int a = 0; sizeof(++a); printf("%d \n",a); // a = 0
typedef c语言允许一个数据类型起一个新的别名(重命名).不能与auto、extern、mutable、static、register等关键字出现在同一个表达式中
typedef 可以把所有合法的定义转化成类型 但是不能初始化
#define宏:预编译时进行的替换
typedef: 类型重命名 编译时进行的类型命名的识别
#define SINT int*
typedef int* PINT;
int main(){
SINT a, b; // int *a, b; 指针与变量结合,a是整型指针,b是整型变量
PINT p,s; // p s 都是整型指针
}
extern 用在全局变量或函数声明前,用来说明“此变量/函数是在别处定义的,要在此引用”
定义:为这个变量分配一块内存并给它取一个名字(变量名) 这款内存的位置不能改变
声明:1)告诉编译器 这个名字已经匹配到一块内存上了
2)告诉编译器 这个名字我先预定了,别的地方不能再使用它来作为变量名
定义与声明最重要的区别: 定义创建了对象并为这个对象开辟了一块空间,而声明的时候没有给分配内存空间
static静态
C语言中 未初始化的变量会被赋值为0, 只能用常量初始化静态变化
C++中 可以用变量初始化静态变量
局部变量(记忆函数): 只有函数第一次调用,执行初始化,再次调用这个函数,这个静态变量也不会再次被初始化,仍是保存的前一次函数调用时的结果 (作用域不变,生存期改变)[如何做到只初始化一次? 在.data存放静态变量时会做是否被初始化的标记]
全局变量: static说明的全局变量只可以在当前c程序文件中使用(作用域受到了限制,生存期不变)
函数: static说明的函数只可以在当前c程序文件中使用(作用域受到了限制,生存期不变)
const 只读变量
const可以修饰变量、数组、指针等 =》 常变量 定义时需要初始化
#define 预编译指令 在预编译阶段展开
const 只读变量在编译运行阶段使用、
宏 仅替换!!
register 寄存器关键字
建议编译器将变量存在CPU内部寄存器中 而不是通过内存寻址访问以提高效率
cpu 32位 寄存器 4byte