1.前言
紧接上文,我们继续叙述关键字相关知识。
2.特定函数
1.EOF关键字
在说scanf函数之前,我们先了解EOF。
#define EOF (-1)
在EOF的定义中,它的本质是一个整型常量-1,它表示"END OF FILE",也就是“文件的结束”的意思。
scanf函数用于读取键盘输入的数据,如果读取失败返回EOF,而读取正常的时候返回的是读取到的数据个数。
在scanf运行的时候,运用ctrl + z快捷键可以让scanf停止读取。
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {
int arr[10] = { 0 };
int i = 0;
int count = 0;
for (i = 0;i < 10;i++) {
printf("%d ",scanf("%d", &arr[i]));
}
printf("\n");
for (i = 0;i < 10;i++) {
printf("%d ",arr[i]);
}
return 0;
}
程序中每从键盘输入一个值就输出输入值的个数,输出结果如下图。
如果每次输入两个值,也就是程序中scanf语句改为
scanf("%d %d", &arr[i],&arr[i + 1])
,那么输出结果就如下。
2.register关键字--寄存器
在计算机中,数据可以存储在寄存器,高速缓存,内存,硬盘,网盘中,空间越小,运行速度就越快,造价就会越高。表格可呈现如下。
类型 | 一般大小 | 速度 |
---|---|---|
寄存器 | 多少字节 | 最快 |
高速缓存 | 多少M | 快 |
内存 | 8G/16G | 中等 |
硬盘 | 500G | 较慢 |
网盘 | 2T | 最慢 |
将一个变量主动放在寄存器中。
register int a = 0;
但一般编译器会主动将一些数据放到寄存器中。
3.typedef关键字
重命名关键字。
typedef int i;
i a = 8;
printf("%d\n",a);
将int类型重命名为i。
重命名结构体类型。
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
typedef struct student {
char name[20];
char sex;
int age;
float grade;
}stu;
int main() {
/*typedef int i;
i a = 8;
printf("%d\n",a);*/
stu s1 = {"Neal",'M',18,4.5f};
printf("%s %c %d %.1f\n",s1.name,s1.sex,s1.age,s1.grade);
return 0;
}
输出结果如下。
4.static关键字
声明静态变量或者静态函数。
1.修饰局部变量
代码如下。
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
void print() {
static int i = 0;
printf("%d\n",i);
i++;
}
int main() {
int n = 0;
while (n < 5) {
print();
n++;
}
return 0;
}
输出结果如下。
根据输出结果,在重新进入函数时,i并没有被重新赋值为0。
这是因为普通的局部变量是放在栈区上的,这种局部变量进入作用域创建,出来作用域释放,但是局部变量被static修饰后,这种变量就放在静态区,放在静态区的变量,创建好后,直到程序结束才释放。
本质上:static的修饰改变了局部变量的存储位置,因为存储位置的差异,使得执行效果不一样。
被static修饰是不影响作用域的!!!但是生命走起发生了变化,变长了。
2.修饰全局变量
static的修饰,会把外部链接属性变成内部链接属性,最终使得全局变量的作用域变小了。
我们创建两个源文件,一个是game.c,一个是game.h。
代码如下。
test.c:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
//extern int a;
int main() {
extern int a;
printf("%d\n",a);
return 0;
}
game.c:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int a = 0;
输出结果如下。
如果把game.c文件中的变量a用static修饰,也就是变成:
static int a = 0;
那么该程序的输出结果如下:
也就是说test.c就不认识变量a这个符号,应验了上面对全局static变量的阐述。
3.修饰函数
类似修饰全局变量,我们直接给出代码演示。
同样创建两个源文件。
test.c:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
extern Add(int a,int b);
int main() {
int a = 5;
int b = 6;
printf("%d\n",Add(a, b));
return 0;
}
game.c:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int Add(int a,int b) {
return a + b;
}
运行结果如下。
如果把game.c中的Add函数前加static关键字,那么运行就会出错。
也就是test.c不认识Add函数。
5.头文件和#define
1.头文件的作用:
①类型的定义;
②头文件的包含;
③函数的声明。
2.#define定义符号和宏。
#define是预处理指令。
#define M 100
这里的M是一个全局常量。
#define MAX(x,y) (x > y ? x : y)
#define ADD(x,y) ((x) + (y))
这里定义了函数。
6.指针
1.演示
首先要理解内存。
地址 == 指针 == 内存单元的编号。
&a
&是取地址符号,a所占内存的4个字节中第一个字节的地址。
int main() {
char ch = 'w';
char* pc = &ch;
*pc = 'b';
return 0;
}
*是解引用操作符。
2.指针变量的大小
x86是32位环境,此时指针变量的大小是4个字节。
x64是64位环境,此时指针变量的大小是8个字节。
#include <stdio.h>
int main() {
//两个类型不同的野指针
char* pc;
int* pi;
printf("%zd\n",sizeof(pc));
printf("%zd\n",sizeof(pi));
return 0;
}
x86环境下都输出4;
x64环境下都输出8。
另外,在C语言中,"%zd"通常用于输出size_t类型的变量,size_t是一种无符号整数类型,用于表示内存大小或数组长度等非负整数值。
7.结构体
用于描述复杂对象,结构体关键字是:struct。
例如,描述一个学生的信息,由名字,性别,年龄组成。
#include <stdio.h>
struct stu {
char name[20];
char sex[5];
int age;
};
int main() {
int num = 0;
struct stu s1 = { "zhangsan","男",20 };
struct stu s2 = { "zhanghan","女",28 };
printf("%s\n",s2.name);
printf("%s\n",s2.sex);
printf("%d\n",s2.age);
}
初识部分结束,目前的知识都只做初步了解。