以下内容建议大家收藏,全是干货,建议反复观看!!!
Let's  Go ! ! !
首先我们把 C89(C90) 的所有关键字进行一下分类,方便大家理解。
数据类型关键字(12个):
char、short、int、long、signed、unsigned、float、double、struct、union、enum、void
控制语句关键字(12个):
1、循环控制(5个)
for、do、while、break、continue
2、条件语句(3个)
if、else、goto
3、开关语句(3个)
switch、case、default
4、返回语句(1个)
return
存储类型关键字(5个)
auto、extern、register、static、typedef
其他关键字(3个)
const、sizeof、volatile
上面我们把32个关键字进行的详细的分类,下面我们对于单个用法进行介绍,go! go! go!
优质内容推荐,建议每天学习:[字符串函数讲解]   [C语言三子棋游戏]  [操作符详细讲解]

目录

char

short

int

long

signed

unsigned

float

double

struct

union

enum

void

for

do

while

break

continue

if

else

goto

switch

case

default

return

auto

extern

register

static

typedef

const

sizeof

volatile


char

字符变量是用类型符char定义字符变量,char的主要作用就是声明字符型变量或函数。

char类型是个1字节,它的取值范围是[-128 , 127]  (-2^7 --- 2^7-1)。

下面我们举几个例子

1. 用char类型定义几个字符串,并且输出

2.  同时我们也可以定义char类型的变量,用整型(%d)输出。

short

类型名为 short int 或 short,声明短整型变量或函数。

short类型为2个字节,它的取值范围是[-32768 , 32767] (-2^15 --- 2^15-1)。

int

int为基本整型,声明整型变量或函数 。

int类型为4个字节,它的取值范围是[-2147483648 , 2147483647] (-2^31 --- 2^31-1)。

long

1、长整型:long int

long int类型为4个字节。

它的取值范围是[-2147483648 , 2147483647] (-2^31 --- 2^31-1)。

2、双长整型:long long int

long long int类型为8个字节。

它的取值范围是[-9223372036854775808 , 9223372036854775807] (-2^63 --- 2^63-1)。

对于long 类型来说,我们输出的时候有特殊的符号来输出,看案例

signed

声明有符号类型变量或函数。
我们知道计算机只认识0和1,所以任何数据到1计算机的底层都会换成0,1,那负数怎么存储呢?肯定这个“-”号是无法存入内存的,怎么办?很好办,做个标记。把基本数据类型的最高位腾出来,用来存符号,同时约定如下:最高位如果是1,表明这个数是负数,其值为除最高位以外的剩余位的值添上这个“-”号;如果最高位是0,表明这个数是正数,其值为除最高位以外的剩余位的值。
#include <stdio.h>
int main(){signed int jj = 1124;  //定义有符号的变量printf("%d\n", jj);return 0;
}

需要说明的是,signed关键字也很宽宏大量,你也可以完全当它不存在,缺省情况下,编译器默认数据为signed类型(char类型数据除外)。

unsigned

unsigned表示的是无符号数据类型,声明无符号类型变量或函数。

被unsigned修饰的变量,其取值范围一定是大于0的。

1、无符号整形    unsigned int            4字节   0 ~ 4294967295

2、无符号短整型 unsigned short int   2字节   0 ~ 65535

3、无符号长整形 unsigned long int    4字节   0 ~ 4294967295

4、无符号字符型  unsigned char       1字节    0 ~ 255

下面我们看几个例子:

下面我们来来练习一下

#include <stdio.h>
int main(){int i = -20;unsigned int j = 10;printf("%d\n", i + j);  //结果为多少?return 0;
}

解析:输出有符号的数据

-20:

1000 0000 0000 0000 0000 0000 0001 0100 原码

1111 1111 1111 1111 1111 1111 1110 1011 反码

1111 1111 1111 1111 1111 1111 1110 1100 补码

10:

0000 0000 0000 0000 0000 0000 0000 1010  原码&&反码&&补码

-20+10

1111 1111 1111 1111 1111 1111 1110 1100

0000 0000 0000 0000 0000 0000 0000 1010  +     (1+1,进1,变0)

-------------------------------------------------------------------------------------------------------------------

1111 1111 1111 1111 1111 1111 1111 0110 补码

1111 1111 1111 1111 1111 1111 1111 0101 反码

1000 0000 0000 0000 0000 0000 0000 1010 原码 (-10)

我们想要了解无符号类型的运算,我们先要会二进制的运算呀!

再来两例子练练

//code1
#include <stdio.h>
int main(){char a = -128;printf("%u\n", a); //输出无符号的数据return 0;
}//code2
#include <stdio.h>
int main(){char a = 128;printf("%u\n", a); //输出无符号的数据return 0;
}

float

float类型也被叫做单精度浮点类型,声明浮点型变量或函数。

float类型为4个字节,它的数值取值范围为[-3.4*10^-38 ~ 3.4*10^38]

小小提示:在vs里面浮点数默认为double类型,解决方法看案例

 解决方法:我们在定义的数后面加上一个f,就不会出现这样的警告啦

#include <stdio.h>
int main(){float n = 3.14f;printf("%f", n);return 0;
}

double

double类型也被叫做双精度浮点类型,声明浮点型变量或函数。

double类型为8个字节,它的取值范围为[-1.7*10^-308 ~ 1.7*10^308]

也有双长精度 long  double,与double类型差不多。

#include <stdio.h>
int main(){double n = 3.14;printf("%lf", n);return 0;
}

注意:关于浮点类型的小细节,重点来啦。

补充内容:关于 %f 和 %lf 的使用

%f和%lf分别是float类型和double类型用于格式化输入输出时对应的格式符号。
其中:
float,单精度浮点型,对应%f。
double,双精度浮点型,对应%lf。

在用于输出时:
float类型可以使用%lf格式
double类型如果使用了%f格式可能会导致输出错误。

在用于输入时:
double 类型使用了%f格式,会导致输入值错误。
float类型使用double类型不仅会导致输入错误,还可能引起程序崩溃。

struct

struct表示的是一种结构体,结构体是一种构造类型,它是由若干个成员组成。其成员可以是一个基本类型数据,也可以是一个构造体类型。struct是声明结构体变量或函数。

下面我们来定义一些基本的结构体

案例1:

#include <stdio.h>
iint main(){struct Student{long int Num;char Name[20];char Sex[20];char Class[20];long long int Tel;}S1 = { 2019, "李四", "男", "网络1902班", 11245201314 },S2 = { 2020, "张三", "女", "网络1902班", 13145201124 };printf("学号:%ld\n姓名:%s\n性别:%s\n班级:%s\n电话号码:%lld\n", S1.Num, S1.Name, S1.Sex, S1.Class, S1.Tel);printf("\n");printf("学号:%ld\n姓名:%s\n性别:%s\n班级:%s\n电话号码:%lld\n", S2.Num, S2.Name, S2.Sex, S2.Class, S2.Tel);return 0;
}

案例2:

//手动输入10个学生的学号,姓名,成绩,并且输出。
#include <stdio.h>
int main(){int i;struct Student{int num;char name[20];int score;}student[10];for (i = 0; i < 10; i++){scanf("%d%s%d", &student[i].num, &student[i].name, &student[i].score);}printf("\n");for (i = 0; i < 10; i++){printf("%3d %3s %3d\n", student[i].num, student[i].name, student[i].score);}return 0;
}

案例3:

//1、输入两个学生的学号,姓名,成绩。
//2、输出成绩高的那一位学生的所有信息。
//3、当成绩一样时,两位学生的基本信息都输出。#include <stdio.h>
int main(){struct Student{int num; //学号char name[20]; //姓名double sore; //成绩}student1, student2; //定义两个结构体变量scanf("%d%s%lf", &student1.num, &student1.name, &student1.sore);scanf("%d%s%lf", &student2.num, &student2.name, &student2.sore);printf("\n");printf("The Higher is:\n");if (student1.sore > student2.sore){printf("No:%d\nname:%s\nsore:%0.1lf\n", student1.num, student1.name, student1.sore);}else if (student2.sore > student1.sore){printf("No:%d\nname:%s\nsore:%0.1lf\n", student2.num, student2.name, student2.sore);}else{printf("No:%d\nname:%s\nsore:%0.1lf\n", student1.num, student1.name, student1.sore);printf("No:%d\nname:%s\nsore:%0.1lf\n", student2.num, student2.name, student2.sore);}return 0;
}

来一个小总结吧:关于struct的三种输出方式 。  直接上代码  Go!

#include <stdio.h>
struct stu{int num;char name[10];char sex;int score;
};int main(){struct stu kg = { 2019112130, "憨憨", 'W', 100 };struct stu *p = &kg;//下面三种输出的结果是一样的printf("%d %s %c %d\n", kg.num, kg.name, kg.sex, kg.score);printf("%d %s %c %d\n", (*p).num, (*p).name, (*p).sex, (*p).score);printf("%d %s %c %d\n", p->num, p->name, p->sex, p->score);return 0;
}

union

union也被称为共同体。union 维护足够的空间来放置多个数据成员中的 ”一种”,而不是为每个数据成员配置空间。在union中所有的数据成员共用一个空间,同一时间只能储存其中一个数据成员,所有的数据成员具有相同的起始地址。声明共用体(联合)数据类型。

enum

enum表示的是枚举类型,利用关键字enum可以声明枚举变量,这也是一种数据类型。使用该类型可以定义枚举型变量,一个枚举变量包含了一组相关的标识符,其中每一个标识符都都对应一个整数值,称为枚举常量。

声明枚举类型。

这里初始化的值有我们自己来定义,后面的逐个真假。

#include <stdio.h>
enum Color{red = 1,blue,green,yellow
};
int main(){enum Color color;scanf("%d", &color);switch (color){case red:printf("red\n");break;case blue:printf("blue\n");break;case green:printf("green\n");break;case yellow:printf("yellow\n");break;}return 0;
}

void

void类型修饰符(type specifier)表示“没有值可以获得”。因此,不可以采用这个类型声明变量或常量。

1、void用于函数声明,没有返回值的函数,其类型为 void。

#include <stdio.h>
void Add(int x,int y){printf("%d\n", x + y);
}
int main(){int gg = 11;int jj = 24;Add(gg,jj);return 0;
}

2、void不能用来声明变量或常量

 3、void是没有返回值的,在void函数里面不能使用return来返回数据。

#include <stdio.h>void new_line(){ //函数1printf("didi\n");
}void three_line(){ //函数2int i = 0;for (i = 0; i <= 3; i++){ //循环调用4次函数1new_line();}
}int main(){three_line(); //输出函数2return 0;
}

for

for表示的是一个循环语句,可以控制一个循环,并且在每一次循环时修改循环变量。在循环语句中for应该是最为灵活的,不仅可以用于循环次数已经确定的情况,而且还可以用于循环次数不确定而只给出循环结束条件的情况。

每个for语句包含了3个用分号隔开的表达式。

我们可以控制变量的自增和自减的大小   代码如下 :

//code1:自增
#include <stdio.h>
int main(){int i;for (i = 0; i < 10; i++){ //每次循环i+1printf("%d ", i);}printf("\n");for (i = 0; i < 10; i+=2){ //每次循环i+2printf("%d ", i);}printf("\n");for (i = 0; i < 10; i += 3){ //每次循环i+3printf("%d ", i);}return 0;
}//code1:自减
#include <stdio.h>
int main(){int i;for (i = 10; i > 0; i--){ //每次循环i-1printf("%d ", i);}printf("\n");for (i = 10; i > 0; i-=2){ //每次循环i-2printf("%d ", i);}printf("\n");for (i = 10; i > 0; i -= 3){ //每次循环i-3printf("%d ", i);}return 0;
}

我们想一下,在for循环中,3个条件都可以省略吗?

1、省略变量初始化

上面因为我们没有对初始化的变量进行赋值,所以报错,我们可以在for循环外面将变量进行赋值,那就不会出现报错啦!

#include <stdio.h>
int main(){int i = 0;  //在for循环外面对变量进行赋值for (; i < 10; i++){printf("%d ", i);}return 0;
}

2、省略循环的判断条件

由上面的实验我们知道,for循环进入了一个死循环了,所以判断条件不能省略。

3、省略变量更新

由上面的实验我们知道,for循环还是进入了一个死循环了。

但是我们可以在for循环里面进行变量更新:

#include <stdio.h>
int main(){int i;for (i = 0; i < 10; ){printf("%d ", i);i++;  //在for循环里面进行变量更新}return 0;
}

4、在for循环里面我们3个条件都不要,看看会怎么样了!

很明显看到,又是一个死循环了。

#include <stdio.h>
int main(){int i = 1;
//下面两个都是死循环的语句for ( ; ; ){}while (1){}return 0;
}

总结:在for循环中,变量初始化和变量更新我们可以省略,但是我们不能省略判定条件,不然for就会进入到一个死循环。

例子:求1-100内所有数的和

#include <stdio.h>
int main(){int i = 0;int sum = 0;for (i = 1; i <= 100; i++){sum += i;}printf("%d\n", sum);return 0;
}

do

do...while是一个比较特殊的循环,因为在有些条件下,不论条件是否满足,循环过程必须至少执行一次。

do...while语句就是先执行循环体语句的内容,然后判断循环条件是否成立。

下面我们看一个例子:

所以我们知道了就算不满足判断条件,循环过程必须至少执行一次。

注意:在使用do...while语句时,条件放在while关键字后面的括号中,最后必须加上一个分号。

例子:我们使用do...while来计算1-100之间所有数的和

#include <stdio.h>
int main(){int n = 1;int sum = 0;do{sum += n;n++;   //这里我们让n进行自加} while (n <= 100);printf("%d\n", sum); //用sum来计算总和return 0;
}

while

while循环语句首先检查一个条件,也就是括号中的表达式。当条件为真时,就执行紧跟其后的语句或者语句块。每执行一遍程序,都将回到while语句处,重新检验条件是否满足。如果一开始就不满足,则跳过循环体中的语句,直接执行后面程序代码。如果第一次检验时满足,那么在第一次或其后的循环过程中,必须得有使条件为假的操作,否则循环将无法终止。

例如下面的代码就是一个死循环

while(iSum<100){iSum+=1;
}while(1){}

例子:我们使用while循环来计算1-100之间所有数的和

#include <stdio.h>
int main(){int n = 1;int  sum = 0;while (n <= 100){sum += n;n++;}printf("%d\n", sum); //计算总和return 0;
}

来一点难度的:用二分法找出找出数组中是否存在你要找的那个数,如果有,输出他的下标,如果没有的话,就输出找不到。

#include <stdio.h>
int main(){int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };int sz = sizeof(arr) / sizeof(arr[0]);//计算元素个数int k = 7;  //被查找的元素int left = 0;//左下标int right = sz - 1;//右下标while(left<=right){int mid = (left + right) / 2;if (arr[mid] > k){right = mid - 1;}else if (arr[mid] < k){left = mid + 1;}else{printf("找到该元素,下标是:%d\n", mid);break;}}if (left > right){printf("找不到!\n");}return 0;
}

break

有时候会遇到这样的情况,不管表达式检验的结果如何,都需要强制结束循环,这时候我们就可以使用break语句。

break语句终止并跳出循环,继续执行后面的代码。

下面是一个死循环。

但是我们可以用break来解决这个死循环

#include <stdio.h>
int main(){while (1){printf("blue");  break;    //直接结束循环,就不会进入死循环}return 0;
}

在很多地方我们都可以用break语句来结束循环,大家可以自己去试一试。

continue

在某些情况下,程序需要返回到循环头部继续执行,而不是像break那样跳出循环。

continue的主要作用就是结束本次循环。就是跳过循环体中尚未执行的部分,直接执行下一次循环的操作。

#include <stdio.h>
int main(){int i;for (i = 0; i < 10; i++){if (i == 5){continue;//当i=5时,直接跳过}if (i == 8){continue;//当i=8时,直接跳过}printf("%d ", i);}return 0;
}

注意:continue语句和break语句的区别:continue语句只能结束本次循环,而不是终止整个循环的执行;break语句则是结束整个循环过程,不再判断执行循环的条件是否成立。

if

if是一种条件语句。If语句通过对表达式进行判断,根据判断的结果决定是否进行相应的操作。

if后面括号中的表达式就是要进行判断的条件,后面的语句部分则是对应的操作。如果if判断括号中的表达式为真,就执行后面语句操作;如果为假值,那么不会执行后面语句部分。

#include <stdio.h>
int main(){int  n;printf("input the num:");scanf("%d", &n);   //手动输入一个数,进行判断if (n > 10){printf("该数大于10\n");}if (n < 10){printf("该数小于10\n");}return 0;
}

else

if...else语句。在if后的括号中判断表达式的结果,如果判断的结果为真,则执行紧跟if后语句块中的内容;如果判断的结果为假,则执行else语句后的语句块内容。也就是说,当if语句检验的条件为假时,就执行相应的else语句后面的语句或者语句块。

#include <stdio.h>
int main(){int  n;printf("input the num:");scanf("%d", &n);   //手动输入一个数,进行判断if (n > 10){printf("该数大于10\n");}else{printf("该数小于10\n");}return 0;
}

例子:给一个不多于5位的正整数,求出它是几位数;

#include <stdio.h>
int main() { int s;printf("请输入一个不大于5位的整数:");scanf("%d", &s);    //手动输入一个数if (s < 10){printf("这是一个1位数\n");}else if (10 <= s && s <= 99){printf("这是一个2位数%d\n",s);}else if (100 <= s && s <= 999){printf("这是一个3位数\n");}else if (1000 <= s && s <= 9999){printf("这是一个4位数\n");}else{printf("这是一个5位数\n");}return 0;
}

goto

goto语句为无条件转移语句,可以使程序立即跳转到函数内部任意一条可执行语句。goto关键字后面带一个标点符,该标点符是同一个函数中某条语句的符号。符号可以出现在任何可执行语句前面,并且以一个冒号“:”作为后缀。

我们来看两个例子

1、goto从上到下

#include <stdio.h>
int main(){
goto end;printf("1\n");printf("2\n");printf("3\n");printf("4\n");
end:printf("5\n");printf("6\n");printf("7\n");return 0;
}

2、goto从下往上  (会进入死循环)

#include <stdio.h>
int main(){             //这个代码会进入一个死循环printf("1\n");      //到了goto永远往上执行,不会停止printf("2\n");printf("3\n");printf("4\n");
end:  printf("5\n");
goto end;printf("6\n");printf("7\n");return 0;
}

使用goto语句跳出循环。

#include <stdio.h>
int main(){int i = 0;int n = 0;for (i = 1; i < 10; i++){printf("The i is:%d\n", i);do{  //使用do...while进行循环printf("enter the number to select\n");printf("(0 is quit,99 for the next step)\n");scanf("%d", &n);  //用户选择输入if (n == 0){goto exit;  //执行goto跳转语句}} while (n != 99);  //判断用户输入}
exit:  //跳转语句执行位置printf("Exit the program!\n");return 0;
}

switch

case

default

因为上面三个关键字通常在一起使用,所以我们就不分开一一举例,我们直接三个一起联合说明。

switch语句是多分支选择语句。
if语句只有两个分支供选择,而在实际问题中常需要用到多分支选择。在c语言中可以用switch语句直接处理多分支选择情况,将程序的代码可读性提高。

switch后面括号中的表达式就是要进行判断的条件。在switch语句块中,使用case关键字表示检验条件符合的各种情况,其后的语句是相应的操作。其中还有一个default关键字,作用是如果没有符合条件的情况,那么执行default后面默认的情况语句。

#include <stdio.h>
int main(){int day;printf("请输入1-7:");scanf("%d", &day);switch (day){case 1:printf("星期一\n");break;case 2:printf("星期二\n");break;case 3:printf("星期三\n");break;case 4:printf("星期四\n");break;case 5:printf("星期五\n");break;case 6:printf("星期六\n");break;case 7:printf("星期天\n");break;default:printf("你输入的有误!\n");break;}return 0;
}

注意:每个语句后面的break都不能省略了,不然就会出现一对多的情况。

最后我们总结一下,switch语句的含义:

return

return 0 代表程序正常退出,return 1代表程序异常退出。

使用return语句可以返回一个变量内的值或一个指针,也可用return0,表示返回为空。

return 代表调到函数外。

return 0代表函数正常终止。return 1代表函数非正常终止。

return 关键字的作用是返回程序流程的控制权。其副作用是返回一个值。

看一个例子:求阶乘

#include<stdio.h>
int Facl(int n){int i = 0;int ret = 1;for (i = 1; i <= n; i++){ret *= i;}return ret;
}
int main(){int n = 0;int ret = 0;printf("请输入一个要求阶乘的数:");scanf("%d", &n);ret = Facl(n);printf("%d\n", ret);return 0;
}

auto

auto:在缺省情况下,编译器默认所有的变量都是auto的,所以autu关键字可以省略。

auto关键字用于定义一个局部变量为自动的,这意味着每次执行到定义该变量时,都会产生一个新的变量,并且对其重新初始化。声明自动变量,一般不使用 。

#include <stdio.h>
void AddOne(){auto int j = 1;      //定义auto变量j = j + 1;           //变量+1printf("%d\n", j);   //显示结果
}int main(){printf("第一次调用:"); AddOne();                //调用函数printf("第二次调用:");AddOne();                //调用函数return 0;
}

extern

extern变量称为外部存储变量。extern声明了程序中将要用到但尚未定义的外部变量。通常外部储存都用于声明在另一个转换单元中定义的变量。 
一个工程是由多个c文件组成的。这些源代码文件会分别进行编译,然后链接成一个可执行的模块。把这样的一个程序作为一个工程进行管理,并且生成一个工程文件来记录所有包含源代码文件。

下面我们通过一个实例来了解一下extern。
首先我们要建立两个c文件。

1、我们在第一个文件里面定义变量

2、我们在第二个文件里面无法使用在第一个文件里面定义的变量

3、这时我们可以使用extern关键字来解决这个问题

由上面的实验,我们没有在第二个文件里面进行定义变量,更没有对变量进行赋值,但是我们输出了变量的数值。所以extern可以调用在别的文件中定义的变量。

//kk.c
#include <stdio.h>
int jj = 1124;  //定义变量并且对变量进行赋值//gg.c
#include <stdio.h>
int main(){extern jj;printf("%d\n",jj);  //1124//我们这里调用了第一个文件里面jj的值return 0;
}

register

register:这个关键字请求编译器尽可能地将变量存在CPU内部寄存器中,而不是通过内存寻址访问以提高效率。注意是尽可能,不是绝对。可以想象,一个CPU的寄存器数量有限,也就那么几个或几十个,如果用户定义了很多很多register变量,那么即便把CPU“累死”也不可能全部把这些变量放人寄存器,可能轮也轮不到你。

使用register关键字修饰符的注意点:

虽然寄存器的速度非常快,但是使用register修饰符也有些限制的: register变量必须是能被CPU寄存器所接受的类型。这意味着register变量必须是一个单个的值,并且其长度应小于或等于整型的长度﹐而且register变量可能不存放在内存中,所以不能用取址运算符“&”来获取register变量的地址。

#include <stdio.h>
int main(){register int j;  //定义寄存器变量j = 1124;        //对j进行赋值printf("%d\n", j);  return 0;       //程序结束
}

static

static变量为静态变量,将函数的内部变量和外部变量声明成static的意义是不一样的。

static的两个重要作用:

1、修饰变量。变量又分为局部变量和全局变量,但它们都存在内存的静态区。

2、修饰函数。函数前加static使得函数成为静态函数。但此处“static”的含义不是指存储方式,而是指对函数的作用域仅局限于本文件(所以又称内部函数)。使用内部函数的好处是:不同的人编写不同的函数时,不用担心自己定义的函数是否会与其他文件中的函数同名。

#include <stdio.h>
void AddOne(){static int j = 1;  //定义static变量j = j + 1;printf("%d\n", j);
}
int main(){printf("第一次调用:");AddOne();printf("第二次调用:");AddOne();return 0;
}

关于static定义的变量被其他文件访问

gg.c (第一个文件)
#include <stdio.h>
static int jj;
int gg; jj.c (第二个文件)
#include <stdio.h>
extern int gg;        //不报错
extern static int jj; //报错,不能定义多个储存类int main(){gg = 11;          //不报错jj = 24;          //报错,类型不同printf("%d %d", gg, jj);return 0;
}

所以由上面的案例我们知道,在其他的文件中定义的变量,我们可以使用extern来声明此变量,供我们来使用,但是如果在其他文件中该变量被static定义了,我们就无法跨文件使用该变量了。

typedef

typedef关键字用以给数据类型取别名(但是该关键字被分到存储关键字分类中,虽然看起来没什么相关性)。

typedef其实就是一个含义:类型重命名

1. 对一般类型进行重命名 。

2. 对结构体类型进行重命名 。

3. 对指针进行重命名 。

4. 对复杂结构进行重命名。

下面我们来看一下实验案例:

1、对整型重命名

 2、对数组的重命名

#include <stdio.h>typedef int i_kg;int main(){i_kg i;i_kg arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };int sz = sizeof(arr) / sizeof(arr[0]);for (i = 0; i < sz; i++){printf("%d ", arr[i]);}return 0;
}

下面我们来一点复杂的,大家尽力思考一下:

#include <stdio.h>typedef int * ptr_t; int main(){ptr_t p1,p2; //问:p1,p2分别是什么类型return 0;
}

const

const是constant的缩写,是恒定不变的意思,也翻译为常量和常数等。很不幸,正是因为这一点,很多人都认为被const修饰的值是常量。这是不精确的,精确来说应该是只读的变量,其值在编译时不能被使用,因为编译器在编译时不知道其存储的内容。

关于const关键字的主要作用:

1. const修饰的只读变量。

2. const修饰一般变量。

3. const修饰数组。

4. const修饰指针。

5.  const修饰函数的参数。

6. const修饰函数参数的返回值。

7. 节省空间,避免不必要的空间分配,同时提高效率。

下面我们开始实验来进行观察const关键字的作用:

1、被const关键字修饰的变量不能直接被修改

2、被const修饰的变量可以使用指针来进行修改

上面案例原码,大家可以自己实验一下

//code1
#include <stdio.h>
int main(){const int jj = 10;jj = 20;  //直接报错printf("%d\n", jj);return 0;
}//code2
#include <stdio.h>
int main(){const int jj = 10;int *p = &jj;*p = 20;printf("%d\n", jj);return 0;
}

关于const重点细节讲解:!!!!!!!!!!!!!!!!!!!!!!!!!!!!

来一个例题吧,我们应该很了解了const 啦 :

请找出下面程序有哪些错误( )。#include <stdio.h>
int main(){int i = 10;int j = 1;const int *p1;//(1)int const *p2 = &i; //(2)p2 = &j;//(3)int *const p3 = &i;//(4)*p3 = 20;//(5)*p2 = 30;//(6)p3 = &j;//(7)return 0;
}答案:6 7
解析: (const修饰的哪个变量,它就不可以被改变。关键字不能修饰关键字,const不修饰int)
const在前,内容不能变;
const在后,指针不能变;
const* ,指针指向为常量;
*const ,指针本身为常量。

这里我们多提一下,关于指针的解引用:

sizeof

sizeof被称为“最冤枉的关键字”,为什么呢??因为很多人都认为sizeof是一个函数。

siezof的主要作用就是计算数据类型长度。

下面我们就来看一下,基本数据类型的字节大小

同时我们也可以使用sizeof来求数组的大小

#include <stdio.h>
int main(){int jj[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };//int为4个字节//我们定义了10个数//所以10*4=40个字节printf("%d\n", sizeof(jj));//40//下面我们求的是数组的空间大小printf("%d\n", sizeof(jj)/sizeof(jj[0]));//10return 0;
}

volatile

volatile关键字和const一样是一种类型修饰符,用它修饰的变量表示可以被某些编译器未知的因素更改,比如操作系统、硬件或者其他线程等。遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问。

我们来看一个例子:

此时编译器对代码进行优化,这是因为在①、2两条语句中,i没有被用作左值(没有被赋值)。这时候编译器认为i的值没有发生改变,所以在①语句时从内存中取出i的值赋给j之后,这个值并没有被丢掉,而是在②语句时继续用这个值给k赋值。编译器不会生成出汇编代码重新从内存里取i的值(不会编译生成装载内存的汇编指令,比如ARM的LDM 指令),这样提高了效率。但要注意:①、②语句之间确认i没有被用作左值才行。

C语言32个关键字详解相关推荐

  1. 由ANSI标准定义的C语言关键字,C语言32个关键字详解

    C语言中32个关键字详解 由ANSI标准定义的C语言关键字共32个: auto double int struct break else long switch case enum register ...

  2. c语言程序关键字是什么,C语言中32个关键字详解

    C语言中32个关键字详解 由 ANSI 标准定义的 C 语言关键字共32个,根据关键字的作用,可以将关键字分为数据类型关键字和流程控制关键字两大类. 一.数据类型关键字 A 基本数据类型(5个) vo ...

  3. c语言中ANSI标准的关键字,C语言中32个关键字详解

    C语言中32个关键字详解 由 ANSI 标准定义的 C 语言关键字共32个,根据关键字的作用,可以将关键字分为数据类型关键字和流程控制关键字两大类. 一.数据类型关键字 A 基本数据类型(5个) vo ...

  4. java语言之super关键字详解

    文章目录 前言 一.super介绍 二.super的语法 三.super内存图 四.super小结 前言 你第一次遇到super关键字是什么时候呢?是不是使用IDEA或者eclipse快捷键生成类构造 ...

  5. C语言 存储类型关键字详解

    今天我们重点说下auto,register,typedef,extern,和static. 让我们进入今天的学习吧!(今天也要加油哦) 1. auto(自动变量) auto作为比较老的关键字,在C语言 ...

  6. C语言之static关键字详解

    目录 前言: 一.几个概念 1.变量 2.局部变量和全局变量 3.变量的作用域 4.变量的生命周期 二.static关键字的作用 三.static关键字修饰局部变量 四.static关键字修饰全局变量 ...

  7. C语言32个关键字与C++62个关键字详解

    C语言32个关键字 关键字 说明 auto 声明自动变量 short 声明短整型变量或函数 int 声明整型变量或函数 long 声明长整型变量或函数 float 声明浮点型变量或函数 double ...

  8. c语言关键字extern作用,C语言中extern关键字详解

    <C语言中extern关键字详解>由会员分享,可在线阅读,更多相关<C语言中extern关键字详解(5页珍藏版)>请在人人文库网上搜索. 1.C 语言中 extern 关键字详 ...

  9. c语言菜单选择如何用字符形式,【创客天地】计算机二级C语言、VB考试详解分析...

    原标题:[创客天地]计算机二级C语言.VB考试详解分析 01 马上就要迎来计算机二级考试了,你准备好了吗?今天助手君准备了一点C语言干货,希望对即将考试的你有所帮助.(上期刚刚推了office,有需要 ...

  10. 嵌入式c语言为什么变量定义在前面,嵌入式C语言数据类型和变量详解

    原标题:嵌入式C语言数据类型和变量详解 一般来讲,标准的C语言类型在嵌入式编译器中是合法的.但由于嵌入式控制器的受限环境.嵌入式c语言的变量和数据类型具有新的特征,这些特征体现在如下方面. 嵌入式C语 ...

最新文章

  1. 有史以来的第一个脚本 找出三个数的最大数字
  2. 来聊一聊Cookie(小甜饼),及其涉及到的web安全吧
  3. 我的世界一进去就java_我的世界国际java版1.12.2加了光影修复进游戏就直接崩溃...
  4. wxWidgets:wxMenu/wxMenuBar 示例
  5. ASP.NET Core 5 在IIS,Nginx,Caddy下的性能测试
  6. Nutshell中的Java 8语言功能-第1部分
  7. java 实现真正的随机数_关于java:SecureRandom的Android实现是否产生真正的随机数?...
  8. 【CodeForces - 1197C】Array Splitting(水题)
  9. 深度学习(六十二)SqueezeNet网络设计思想笔记
  10. Redis万字总结,面试必备
  11. mozilla原代码编译
  12. 倩女幽魂7月20日服务器维护,倩女幽魂手游2021年7月22日更新公告
  13. 酉矩阵、克罗内克积/和 脑图总结
  14. 【中级计量经济学】Lecture 1 计量经济学初步
  15. WORD文档怎么转换成EXCEL
  16. android jcenter google 镜像
  17. inter处理器(CPU)的分类
  18. 国际版抖音Tik Tok怎么引流变现,卖家所不知道的那些事
  19. 5、获取蓝牙设备列表(getBluetoothDevices)
  20. 自动驾驶目标识别-----毫米波雷达学习笔记(1)

热门文章

  1. .Net Frame安装心得
  2. 代码格式化工具 Clang-format
  3. iperf基本使用方式
  4. 中国纺织行业前景动态分析与投资战略研究报告2022-2028年
  5. Rost CM使用手册
  6. 台大matlab教程笔记
  7. 网络安全基础知识笔记
  8. TFTP软件测试自学,tftp
  9. linux ulipad,如何在windows下安装配置python工具Ulipad
  10. 大学报到前最后的技术——VMware探究