一.关键字介绍
1.关键字总类:
auto 局部变量(自动储存)
break 无条件退出程序最内层循环
case switch语句中选择项
char 单字节整型数据
const 定义不可更改的常量值
continue 中断本次循环,并转向下一次循环
default switch语句中的默认选择项
do 用于构成do.....while循环语句
double 定义双精度浮点型数据
else 构成if.....else选择程序结构
enum 枚举
extern 在其它程序模块中说明了全局变量
float 定义单精度浮点型数据
for 构成for循环语句
goto 构成goto转移结构
if 构成if....else选择结构
int 基本整型数据
long 长整型数据
register CPU内部寄存的变量
return 用于返回函数的返回值
short 短整型数据
signed 有符号数
sizeof 计算表达式或数据类型的占用字节数
static 定义静态变量
struct 定义结构类型数据
switch 构成switch选择结构
typedef 重新定义数据类型
union 联合类型数据
unsigned 定义无符号数据
void 定义无类型数据
volatile 该变量在程序中执行中可被隐含地改变
while 用于构成do...while或while循环结构
main 主函数
printf 打印
system 执行
记事本 notepad();
进程管理 tasklist();
等待 getchar();
2.关键字typedef介绍
(1)定义:重新定义数据类型(把复杂极长的数据类型用简短的名字替代,多用于结构体)
(2)简单举例:
unsigned int a=0;//unsigned int为无符号整形,是一个整体
int b=0;
我们可以看到要是每次都打unsigned int,很浪费时间,所以我们可以将它缩写
typedef unsigned int unit;//缩写为unit typedef int I int main() { //unsigned int a=0; unit a=0;//与上面的效果一样 //int b=0; I b=0; return 0; }
显而易见,用缩写可以做到节约时间跟成本
3.关键字static
(1)定义:用来修饰变量和函数
(2)修饰局部变量:局部变量被static修饰后,称为静态局部变量。
举例:我们想调用函数打印 1 2 3;如果是按照下面这么写代码,则打印结果为1 1 1
#include<stdio.h> int test() { int j=0; j++; printf("%d",j);//打印了三次 } int main() { int i=0; while(i<3)//循环三次 { test();//调用了三次函数 i=i+1; } return 0; }
为什么程序运行的结果会是1 1 1呢?首先,每次调用test函数,然后进入test函数,然后创建局部变量j,接下来打印完则回到while循环接着调用,再次回到while循环的时候,因为局部变量j已经出了作用域而被销毁,再次进入test函数则需要重新创建,此时又是从0开始,因而每次打印结果都是1。
为了达到目的,我们就可以使用到关键字static
#include<stdio.h> int test() { static int j=0;//修饰后使其出了作用域也不会被销毁 j++; printf("%d",j);//打印了三次 } int main() { int i=0; while(i<3)//循环三次 { test();//调用了三次函数 i=i+1; } return 0; }
局部变量被static修饰后,使其出了作用域也不会被销毁,变量j因而被保留下来。在第一次进入函数后,j的值变成1,当再次进入后,因为变量j还存在,不会再次创建,所以打印结果会是1 2 3
(3)修饰全局变量
我们现在有两个文件(.c文件):a文件和b文件。
本来在a文件上创建的全局变量在b文件中声明就可以使用,但是被static修饰后则无法使用。
(4)修饰函数
我们现在有两个文件(.c文件):a文件和b文件。
本来在a文件上创建的函数在b文件中声明就可以使用,但是被static修饰后则无法使用。
二.#define定义常量和宏
1.#define定义的常量
(1)怎么定义:
#define M 100//类似头文件 #define ch 'A'//定义了一个字符常量
(2)如何使用:
#include<stdio.h> #define M 100 #define ch 'A' int main() { //直接打印 printf("%d",M); printf("%c",ch); //定义数组 int a[M]={0}; return 0; }
这样定义的常量跟普通常量没有区别,可以理解为:给100重新取了个名字,给字符A重新取了个名字。(这样定义的好处,后续需要更改常量的值,只需要修改重新起的名字即可,如:M,ch)
2.#define定义宏
(1)总结:宏可以有参数 宏是一种替换
(2)替换一些简单的函数:
#include<stdio.h> int Add(int x,int y) { int z=0; return z=x+y; } int main() { int a=3; int b=4; c=Add(a,b); printf("%d\n",c); return 0; }
用宏可以这样写:
#include<stdio.h> #define Add(x,y)(x+y) int main() { int a=3; int b=4; c=Add(a,b); printf("%d\n",c); return 0; }
三.指针
1.介绍内存跟定义
计算机内存被划分为一个个单元,每个单元的单位是一个字节。每个单元都有一个编号,该编号称为该内存单元的地址。在c语言中,该地址称为指针。
我们举例说明:把内存看作酒店,每一个单元看成一个房间,编号就看成房间的房间号,房间号也可以称为地址,我们可以通过该房间号(地址)找到该房间。每个房间里面可以存放东西,这个东西在c语言上面称为数据。
比如,我们创建一个整形变量(int),它的内存大小是四个字节,则需要找到四个连续的单元来存放该整形变量,这个时候我们需要把四个单元看成一个整体。要找到这个整体,只需要找到该整体中第一个单元的编号即可
存疑:地址怎么来
2.举例说明:
#include<stdio.h> int main() { //&:取地址符号 *解引用操作符 int a=5; int* p=&a; //&a是取出变量a的首地址,然后存放到变量p中。 //*说明p是指针变量。地址==指针==编号 //用来存放地址的变量称为指针变量 //int是在说明p指向的是int类型的变量(int类型的指针变量) //*p 通过地址找到地址所指向的对象 return 0; }
变量 | 存放的内容 | 变量的地址 |
a | 5 | 0x00004 |
*p | 0x00004 | 0x00012 |
如果再用一个变量存放指针变量p的地址,该变量称为二级指针,也叫指针的指针,当前不需要了解。
当我们需要修改变量a中存放的值时,可以这样
#include<stdio.h> int main() { int a=5; int* p=&a; *p=520;//通过地址找到地址所指向的对象,所以*p==a return 0; }
3.指针变量的内存
因为指针是用来存放地址的,所以指针变量所需的内存都是4个字节(32位);8字节(64位)
4.常用案列
题目:用函数交换两个数的值
错误写法;
#include<stdio.h> void swap(int x,int y) { int z=0; z=x; x=y; y=z; return; } int main() { int a=10; int b=20; printf("%d %d",a,b);//交换前 swap(a,b); printf("%d %d",a,b);//交换后 return 0; }
我们可以看到,是把a和b的值传给形参x和y,问题就来了,形参值的改变会影响实参(a和b)的值吗,答案是不会影响,因为传值的时候,形参是实参的一份拷贝。复印件的改变不会影响到原件。所以两次打印的结果都是10 20。
那就需要用到指针,通过地址找到对象,然后在根本上改变。
正确写法:
#include<stdio.h> void test(int* x,int* y) { int temp=0;//两个数交换必须借助第三方 temp=*x; *x=*y; *y=*x; } int main() { int a=10; int b=20; printf("%d %d",a,b);//交换前 test(&a,&b);//将a和b的地址传递给指针x和y printf("%d %d",a,b);//交换后 return 0; }
底层逻辑是要改变实参,就是改变地址。
四.结构体
1.定义
结构体也是数据类型中的一种。像int是一种,但是其只能描述一种类型。如果描述年龄,可以用int描述,身高可以用double描述,但是一个学生该又怎么样描述呢?所以我们需要用到结构体类型去描述一些复杂对象。
2.如何定义
(1)定义类型
struct Stu//这个是一个类型,跟int一样,用来创建变量 { char name[20]; int age; };
(2)创建变量(初始化)
#include<stdio.h> struct Stu//这个是一个类型,跟int一样,用来创建变量 { char name[20]; int age; }; int main() { struct Stu s1; struct Stu s2;//创建了两个变量s1和s2 //赋值 struct Stu s1={'苏芸',20}; struct Stu s2={'贾语',19};//分别对名字和年龄进行赋值 }
(3)结构体的使用
直接使用变量
#include<stdio.h> struct Stu//这个是一个类型,跟int一样,用来创建变量 { char name[20]; int age; }; int main() { struct Stu s1; struct Stu s2;//创建了两个变量s1和s2 //赋值 struct Stu s1={'苏芸',20}; struct Stu s2={'贾语',19};//分别对名字和年龄进行赋值 printf("%s %d\n",s1.name,s1.age);//通过变量找到结构体内部的成员,中间用点(.) printf("%s %d\n",s2.name,s2.age); return 0; }
使用地址:
#include<stdio.h> struct Stu//这个是一个类型,跟int一样,用来创建变量 { char name[20]; int age; }; int main() { struct Stu s1; struct Stu s2;//创建了两个变量s1和s2 //赋值 struct Stu s1={'苏芸',20}; struct Stu s2={'贾语',19};//分别对名字和年龄进行赋值 struct Stu* p=&s1; printf("%s %d",p->name,p->age); return 0; }
总结:结构体变量.结构体成员 结构体指针->结构体成员