我们继续第二部分《初识C语言》的学习,上一篇学习笔记当中我们详细学习了函数、数组以及常见操作符,今天我们继续后面内容的学习,接下来的内容还包括: 常见关键字 、#define 定义常量和宏 、指针 、结构体。
第二部分 初识C语言
十一、常见关键字
// C语言提供了丰富的关键字,这些关键字都是语言本身预先设定好的,用户自己是不能创造关键字的
// 我们在创建变量的时候应该避免变量名与关键字冲突/*C语言的关键字有如下:auto break case char const continuedefault do double else enum externfor goto if int long registerreturn short signed sizeof static structswitch typedef union unsigned void volatilewhile float
· 其中我们大概分为几大类
1、与类型相关:auto const char int short long enum float double union struct signed unsigned static void typedef
2、与循环相关:break continue do while for
3、与分支相关:goto if else switch case default
extern —— 声明外部符号
register —— 寄存器
return —— 函数返回
sizeof —— 计算所占内存大小
volatile —— 后期会有介绍
*//*
接下来我们学习几个关键字
register —— 寄存器
· 在计算机上,数据都可以储存在哪里?
1、 寄存器 (单位是字节)
2、高速缓存 (单位是MB)
3、内存 (8G/16G)
4、硬盘 (500G/1T)
5、网盘 (几个T)
由 5 - 1 速度越来越快,造价越来越高,空间越来越小 typedef —— 类型重命名
*/#include<stdio.h>typedef unsigned int uint; // 将 unsigned int 类型重命名为 uint int main()
{register int a = 0; // 建议编译器将变量a放置于寄存器当中,但并不是直接放置于寄存器中// 如果成功将变量放置于寄存器中,则运行时间将会缩短unsigned int age = 0; // 定义一个无符号整型uint high = 0; // 定义了一个无符号整型// 这里的 age 和 high 是同样类型的return 0;
}/*
static(静态的)
· 修饰局部变量 —— 静态局部变量
· 修饰全局变量 —— 静态全局变量
· 修饰函数
*/#include <stdio.h>
void test()
{int i = 0;i++;printf("%d ", i);
}
int main()
{int i = 0;for (i = 0; i < 10; i++){test();}return 0;
}
// 上面这段代码是我们好理解的,运行结果是打印 10 个 1#include <stdio.h>
void test()
{//static修饰局部变量static int i = 0;i++;printf("%d ", i);
}
int main()
{int i = 0;for (i = 0; i < 10; i++){test();}return 0;
}
// 这里仅仅是将变量 i 使用 static 进行修饰,运行结果却是打印 1 到 10
// 所以说 static 修饰局部变量改变了变量的生命周期(不影响作用域)
// 让静态局部变量出了作用域还存在,到程序结束,生命周期才结束/*我们往往把内存分为栈区、堆区和静态区
· 栈区:存放局部变量、函数参数 (临时变量)进了作用域创建,出了作用域就释放
· 堆区:动态内存分配(malloc calloc realloc free)
· 静态区:静态变量、全局变量放在静态区的数据创建后,直到程序结束才释放
也就是说,原本放在栈区上的变量,因为 static 的修饰,存放在了静态区(改变了存储位置)
*/// 下面我们来看 static 对全局变量的影响
// 在add.c源文件中
int g_val = 2018;
// 在test.c源文件中
extern int g_val;
int main()
{ printf("%d\n", g_val);return 0;
}
// 这段代码是可以正常运行打印的// 但如果改成如下这样
// 在add.c源文件中
static int g_val = 2018;
// 在test.c源文件中
int main()
{printf("%d\n", g_val);return 0;
}
// 在编译的时候会出现连接性错误
// 结论:一个全局变量被static修饰,使得这个全局变量只能在本源文件内使用,不能在其他源文件内使用。
// 全局变量本身是具有外部链接属性的,在 A 文件中定义,在 B 文件可以通过“链接”使用
// 但是如果全局变量被 static 修饰,就从外部链接属性变为了内部链接属性,只能在本文件中使用
// 使得全局变量的作用域变小了// 下面我们来看 static 对函数的影响
// 在add.c源文件中
int Add(int x, int y)
{return x + y;
}
// 在test.c源文件中
extern int Add(int x, int y); // 声明外部符号int main()
{printf("%d\n", Add(2, 3));return 0;
}
// 这段代码是可以正常运行的,打印输出 5// 但如果改成如下这样
// 在add.c源文件中
static int Add(int x, int y)
{return x + y;
}
// 在test.c源文件中
extern int Add(int x, int y); // 声明外部符号int main()
{printf("%d\n", Add(2, 3));return 0;
}
// 在编译的时候会出现连接性错误
// 结论:一个函数被static修饰,使得这个函数只能在本源文件内使用,不能在其他源文件内使用。
// 函数本身是具有外部链接属性的,被 static 修饰,就从外部链接属性变为了内部链接属性,只能在本文件中使用// 剩余关键字在后面的学习中都会逐渐遇到逐渐学习
· 关于 EOF 以及 scanf 返回值
// 在这里补充一下关于 EOF 以及 scanf 返回值
// EOF 的本质就是 -1 (end of file)
// scanf 函数读取失败的时候就会返回EOF
// 如果读取正常的话,返回的是读取到的数据的个数// 比如我们来看下面这段代码的例子#include<stdio.h>int main()
{int a = 0;int b = 0;scanf("%d %d", &a, &b);int ret = scanf("%d %d", &a, &b);printf("ret = %d", ret);printf("a = %d", a);printf("b = %d", b);return 0;
}/*这段代码在正常情况下 ret 会输出 2a 和 b 会输出用户输入的数值但是如果代码输入 Ctrl + Z 进行强制退出那么 ret 的数值就会显示 -1 即 EOF 的数值
*/
十二、#define定义常量和宏
#define M 100 // 定义符号(标识符常量)
#define MAX(x,y) (x > y ? x : y) // 定义宏 —— 处理相对简单逻辑
// 这个宏也可以写成函数,实现同样功能
int Max(int x ,int y)
{if (x >= y)return x;elsereturn y;
}
#define ADD(x,y) ((x)+(y)) // 这也是个宏,实现返回两个参数相加#include<stdio.h>int main()
{printf("%d\n", M);int a = 10;int b = 20;int m = MAX(a, b); //使用宏// 这句话相当于int m = (a > b ? a : b);printf("%d\n", m);return 0;
}
以上是本篇笔记的内容,我们学习了常见关键字以及#define定义常量和宏的相关知识,在接下来的笔记中,我们依旧会继续第二部分的学习,接下来的内容还包括指针和结构体,这两个知识点都是C语言中非常重要的知识,在学习完这两个知识点后,我们会再进行一篇练习文章,从而结束我们第二部分——《初识C语言》的学习。