首先我们来看下c语言中的关键字
auto break case char const continue default do double else enum extern float for goto if int long register return short signed sizeof static struct switch typedef union unsigned void volatile while
c语言中有很多的关键字,在这里我们先介绍几个,后续还会给大家继续更新:
1.typedef:作用相当于给一个类型起别名,简称类型重命名,下面我们来看一段代码吧
#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> typedef int INT; int main(){ //关键字typedef:相当于给类型起一个别名,相当于类型重命名 INT a = 10; printf("a的值为%d\n",a); return 0; }
此时我们把int类型重新命名为INT,那么此时我们可以在主函数中定义一个INT类型的变量并进行输出
输出结果为:
2.static:在c语言中,static是用来修饰变量和函数的,此关键字不管是在c++,java,c中都是非常重要的关键字,也是面试中常考的考点
作用:1.修饰变量:既可修饰全局变量也可修饰局部变量,可分为静态局部变量和静态全局变量(在下面的数据类型介绍中我们将给出静态常量和普通常量的区别)
2.修饰函数--静态函数
3. define定义标识符常量和宏
话不多说我们直接上代码,首先我们对标识符常量进行讨论,现在我们要求圆的面积,但是π此时的值我们并不确定,现在暂定为3.14,那么此时我们如果要随时对这个π进行修改的话
该如何定义这个π呢?此时我们可以define定义标识符常量的方法来定义
#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> #include<math.h>//此头文件里面包含了库函数pow() #define PI 3.14//define定义了一个标识符常量 int main(){ double p = PI*pow(2,2); printf("圆的面积为%f\n",p);//输出圆的面积 /*PI = 99;而且此时我们所定义的标识符常量是不能进行修改的,否则会报错*/ return 0; }
此时要注意的是:我们所定义的标识符常量是不能被重新赋值的,否则会出现如下的错误:
此外我们还可以定义宏:下面来看一段代码:若我们想算两数相加,用宏该如何定义呢?
#define _CRT_SECURE_NO_WARNINGS 1 #define SUM(X,Y) ((X)+(Y))//define定义宏 #include<stdio.h> int main(){ int a = 8; int b = 17; int c = 5*SUM(a+2, b+3);//等价于5*((8+2)+(17+3))=150 printf("%d\n",c);//输出结果为150 return 0; }
输出结果为:
下面将c语言中常见的数据类型做个列举:
数据类型 |
介绍 |
int |
整型 |
short |
短整型 |
long |
|
long long |
|
float |
单精度浮点数 |
double |
|
对此我们可以提出一个问题,每种类型的大小到底是多少呢?
首先在这里介绍下如何求字节大小的方法:sizeof()
sizeof()可用来求字节的大小,在这里要注意sizeof()方法不是库函数,而是关键字
下面我们通过运行程序来看下每种类型的大小
1.在32位windows系统中运行
#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> int main(){ //sizeof方法用来求字节的大小,且sizeof并不是库函数,而是关键字 printf("%d\n", sizeof(char));//1个字节 printf("%d\n", sizeof(short));//2个字节 printf("%d\n", sizeof(int));/*注意int字节在16位中为2个字节,在32位和64位中为4个字节*/ printf("%d\n", sizeof(long));/*注意long字节在windows系统中都为4个字节,在linux64位系统中long占八个字节*/ printf("%d\n", sizeof(long long));//8个字节 printf("%d\n", sizeof(float));//4个字节 printf("%d\n", sizeof(double));//8个字节 printf("%d\n", sizeof(long double));//8个字节 return 0; }
运行结果为:
此时我们可以看到在32位系统中char字符为1个字节,int字符为4个字节,short字符为2个字节,long字符为4个字节,long long字符为8个字节,float字符为4个字节,double字符为8个字节,long double字符为8个字节
2.在64位windows系统中运行
#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> int main(){ //sizeof方法用来求字节的大小,且sizeof并不是库函数,而是关键字 printf("%d\n", sizeof(char));//1个字节 printf("%d\n", sizeof(short));//2个字节 printf("%d\n", sizeof(int));/*注意int字节在16位中为2个字节,在32位和64位中为4个字节*/ printf("%d\n", sizeof(long));/*注意long字节在windows系统中都为4个字节,在linux64位系统中long占八个字节*/ printf("%d\n", sizeof(long long));//8个字节 printf("%d\n", sizeof(float));//4个字节 printf("%d\n", sizeof(double));//8个字节 printf("%d\n", sizeof(long double));//8个字节 return 0; }
运行结果为:
此时我们可以看到在64位系统中char字符为1个字节,int字符为4个字节(而int字符在16位中占两个字节),short字符为2个字节,long字符为4个字节(而long字符在linux64位系统中占8个字节),long long字符为8个字节,float字符为4个字节,double字符为8个字节,long double字符为8个字节。
通常来说1 byte(B)=8 bit
字节再大一点就是KB 1KB=1024B
接下来是MB,1MB=1024KB
再大就是GB,1GB=1024MB
还有就是TB,1TB=1024GB
常量与变量
一:变量
1.定义变量的方法:
int age=10; float weight=45.5f; char ch='w';
2. 变量的分类
局部变量:定义在方法内部的变量(分为普通局部变量与静态局部变量)
全局变量:定义在方法外部的变量(分为普通全局变量与静态全局变量)
#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> int b = 15;//此时b为全局变量,写代码尽量不要写全局变量 int main(){ int c = 20;//局部变量 int b = 30;//此时b为局部变量 printf("%d", b);//输出结果为30,因为局部变量优先使用
此处注意我们在主函数外定义了一个全局变量b,主函数内定义了一个局部变量b,此时我们若要输出这个局部变量的话,值应该为30,原因是当全局变量与局部变量同名时,局部变量优先的原则。
输出结果:
3.变量的使用(主要介绍static关键字)
(1)首先介绍下scanf输入语句,下面先看一段代码:
#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> int main(){ int sum1, sum2; scanf("%d%d", &sum1, &sum2);/*此处注意%d与%d之间 不需要空格,因为不空格与空格在命令框进行输入的时候 都必须自动空一格进行输入,*/\ printf("输出的值为%d,%d\n", sum1, sum2);/*此处输出在命令框输入的 数字*/ int sum3 = sum1;/*sum3为变量,变量由字母,数字,下划线 组成,变量的命名最好是小驼峰形,例如max_Num等,且 变量开头不能以数字开头*/ int sum4= sum2; int sum5= sum3 + sum4; printf("和为%d\n", sum5);//输出结果为30 return 0; }
注意:1.在scanf中的%d之间可空格可不空格,原因是不管是否空格,我们在命令行进行输入的时候都是要空一格进行输入的。
2.注意变量命名的规范,变量是由字母,数值,下划线构成,变量的命名最好是小驼峰形,例如max_Num等,且变量开头不能以数字开头。
(2)static的作用
1.修饰局部变量与全局变量
其次我们来看下普通局部变量与静态局部变量的区别:观察下面两段代码,如果我们想此时输出1到10这十个数字的话,哪个方法对呢?
#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> //普通局部变量举例 void Test()//创建一个Test函数 { int i = 0; i++; printf("%d\n",i); } int main(){ int i = 0; for (; i < 10; i++) { Test();//Test的调用 } return 0; }
上述代码的输出结果为:
#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> //静态局部变量举例 void Test()//创建一个Test函数 { static int i = 0; i++; printf("%d\n",i); } int main(){ int i = 0; for (; i < 10; i++) { Test();//Test的调用 } return 0; }
上述代码的输出结果为:
从上述两段代码的对比中我们可以看出一个在Test方法中的i前加了static,一个并没有加,那么到底有什么区别呢?
分析:此处的区别主要在于普通局部变量和静态局部变量的生命周期的不同,普通局部变量的生命周期从函数创建开始到函数结束销毁,而静态全局变量的生命周期从函数创建开始到程序结束时才销毁。
首先对于图一,当变量不是静态局部变量,我们在主函数中每次调用Test方法时,i=0,i++后成1,输出i=1后便返回到了主函数for循环的i++语句中,此时对Test方法的调用已经结束,Test函数的局部变量i的生命周期也已经结束,那么i的值此时又重新变成了0,(并且此处我们重复定义i并没有错,因为一个i只在Test方法中起作用,一个是在是主函数中作用),此时主函数中的for循环相当于计数器的作用,他一共会调用十次Test方法,但是Test方法中的i每次递增到1时函数便会调用结束并且i会重新变为0等待下一次对Test方法的调用,所以最后的输出结果为十个1.
对于图二加入了static后,此时变成了静态局部变量,静态的局部变量的生命周期在程序结束时才会消失,所以当我们每次在for函数中结束Test方法的调用后i的值不会变为0,而是会保留递增后的值,当for循环结束后,也就是程序结束后,此时Test方法中的i的生命周期才会结束,所以最后的输出结果为1到10十个数字。
最后我们来看下普通全局变量与局部全局变量的区别:现在我们来思考一个问题:如果我们在一个.c文件中定义了一个普通全局变量,那么我们在另一个.c文件中要怎么调用这个普通全局变量呢?
如果是一个静态的全局变量,此时还能调用成功吗?那么我们来看两段代码:
#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> int global = 10;
此处我们在一个.c文件中定义了一个普通全局变量global.
#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> extern int global;//此时会在我的整个工程的.c文件中找我的global变量 int main(){ int a = 10; int b = a + global; printf("%d\n", global);//此时我们在另一个.c文件中找到了我们的global变量,输出值为10 printf("%d\n",b); return 0; }
因为普通全局变量的作用域为整个工程,那么此处我们想要引用另一个.c文件中的普通全局变量global,就要用到一个非常重要的关键字extern,extern关键字的作用为引入外部符号当使用此关键字时,会在整个工程中寻找普通全局变量global,此时我们在主函数中输出global时便可输出10这个数字了,并且可以随时调用global这个变量。
其次,如果我们将第一个.c文件中的普通全局变量global变为静态的全局变量,那么此时在另一个.c文件中便不能再用关键字extern对global变量进行调用了,原因是当global变量被static进行修饰时,其作用域为当前的.c文件内,那么当我们在另一个.c文件中使用extern关键字时便不能再进行调用了,会发生如下错误
此段代码的输出结果为:
2.修饰函数
static既可以修饰变量,又可以修饰函数,还是同样的问题:如果我们在一个.c文件中定义了一个普通全局函数,那么我们在另一个.c文件中要怎么调用这个普通全局函数呢?
如果是一个静态的全局函数,此时还能调用成功吗?此时我们来看两段代码:
#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> int Add(int x, int y){ return x + y; }
此处我们在一个.c文件中定义了一个普通全局函数Add.
#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> extern int Add(int x, int y); int main(){ int a = 2; int b = 4; int c = Add(a, b); printf("c的值为%d\n", c); return 0; }
此时我们要在当前的.c文件内调用另一个.c文件中的Add方法,此时我们仍然是使用extern关键字进行调用,输出c的值为6
其次,如果我们将第一个.c文件中的普通全局函数Add变为静态的全局函数,那么此时在另一个.c文件中便不能再用关键字extern对全局函数Add进行调用了,原因是当普通全局函数Add被static进行修饰时,其作用域为当前的.c文件内,那么当我们在另一个.c文件中使用extern关键字时便不能再进行调用了,会发生如下错误:
此段代码的输出结果为:
4.变量的作用域和生命周期
作用域:
1. 普通局部变量的作用域是变量所在的局部范围,即花括号内。
2. 静态局部变量的作用域仍是变量所在的局部范围内,即花括号内。
1. 普通全局变量的作用域是整个工程。
2. 静态全局变量的作用域是当前.c文件中。
生命周期:
变量的生命周期指的是变量的创建到变量的销毁之间的一个时间段
1. 普通局部变量的生命周期是:进入作用域生命周期开始,出作用域生命周期结束(即从函数的创建到函数结束消失)。
2. 静态局部变量的生命周期是:从函数的创建到程序的结束
1. 普通全局变量的生命周期是:整个程序的生命周期,即程序运行的时候创建,程序运行结束消失
2.静态全局变量的生命周期是:整个程序的生命周期,即程序运行的时候创建,程序运行结束消失
二:常量
C语言中的常量分为以下以下几种:
字面常量(下面将会介绍)
const 修饰的常变量(注意1.此处当变量被const修饰后,其值不能在变化.2.在定义的同时必须进行初始化)
#defifine 定义的标识符常量(上述已经介绍)
枚举常量(下面将会介绍)
下面我们来看一段代码:
/**c语言中常见的常量 */ #define _CRT_SECURE_NO_WARNINGS 1 #define SIZE_I11 22//define定义的标识符常量 #include<stdio.h> enum Sex{//枚举常量 MALE, FEMALE, SECRET }; int main(){ 3.14;//字面常量 const int a = 10;/*被const修饰后,其值不能再发生改变 且定义的同时进行初始化*/ printf("MALE的值为%d\n", MALE);//此时默认的输出结果为0 printf("FEMALE的值为%d\n", FEMALE);//此时默认的输出结果为1 printf("SECRET的值为%d\n", SECRET); //此时默认的输出结果为2 return 0; }
此时我们可以得出MALE,FEMALE,SECRET的值为0,1,2,因为系统是默认赋值的
上述输出结果为:
思考:此时我们若给枚举变量赋值的话,结果会是什么呢?下面我们来看一段代码:
#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> enum Sex{//枚举常量 MALE, MIDDLE, FEMALE=99,//此时将FEMALE改成99 SECRET, }; int main(){ printf("MALE的值为%d\n", MALE);//此时默认的输出结果为0 printf("MIDDLE的值为%d\n", MIDDLE);//此时默认的输出结果为1 printf("FEMALE的值为%d\n", FEMALE);//此时默认的输出结果为99 printf("SECRET的值为%d\n", SECRET); //此时默认的输出结果为100 return 0; }
此时我们可以得出MALE,MIDDLE,FEMALE,SECRET的值分别为0,1,99,100,原因是当我们给FEMALE赋值为99时,那么它之后的变量会依次递增加1,其之前的变量会从0开始默认加1递增。
上述输出结果为: