常见关键字
在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
『排序不分先后』
接下来,是对其中部分关键字 做的一些说明:
typedef
typedef ———— 类型定义(类型重定义)
当我们对一个类型不满意,我们对它重命名,比如说:
将unsigned int 重命名为uint
但我觉得这个unsigned int 写起来好长啊!
我要它变短一点,方便书写。
我们对它进行重定义、重命名
typedef unsigned int uint;
uint num2 = 10; //等同于unsigned int num1 = 10;
这就是对类型不满意的时候,对它的重命名
接下来,我们看一下,下面这个代码的含义
typedef struct Node
{
int data;
struct Node* next;
}Node;
如果去掉typedef和末尾的Node,剩下的是:
struct Node
{
int data;
struct Node* next;
}; //一个结构体类型 结构体类型名:struct Node
那前面的代码就可以看出来是:
对结构体类型的重定义,对这个结构体类型重命名为Node
使用时:比如说:定义一个结构体名为 n 的结构体
Node n; //写起来方便一点,相当于重定义之前的 struct Node n;
static
static 有三种修饰对象:
修饰局部变量
修饰全局变量
修饰函数
1. static 修饰局部变量,可延长变量生命周期
void test()
{
int i = 0;
i++;
printf("%d", i);
}
int main()
{
int i = 0;
for (i = 0; i < 10; i++)
{
test();
}
return 0;
}
猜猜上面代码的输出结果是什么?
输出结果:
void test()
{
int i = 0; //这个 i 是局部变量,局部变量的生命周期仅在代码块内部
i++; //每执行一次test,就重新创建一次i = 0,然后i++,i等于1
printf("%d", i); //每执行一次test,打印一次i,
}
int main()
{
int i = 0;
for (i = 0; i < 10; i++) //循环10次
{
test(); //test执行10次
}
return 0;
}
但是:
void test()
{
static int i = 0; //把局部变量 i 用static修饰
i++;
printf("%d", i);
}
int main()
{
int i = 0;
for (i = 0; i < 10; i++)
{
test();
}
return 0;
}
输出结果会发生变化吗?
让程序走一遍:
分析:
第一次进入test(),i=0;i++;此时i=1;打印:1
第二次进入test(),i由于第一次被static修饰,而使生命周期延长(即在上次执行完test()函数后,i没有被销毁)且第二次不被执行,i=1;i++;此时 i=2;打印:2 ……
局部变量:进入函数时被创建,而执行完函数时被销毁。
static修饰局部变量:使得再次执行这个函数时,这个变量还在,且值为上一次执行完时的值
static修饰局部变量的作用:改变了这个局部变量的生命周期,不改变它的作用域,它还是只能在这个函数内被使用,整个程序执行结束时static修饰的局部变量才被销毁
2. static 修饰(静态)全局变量 改变作用域
在项目的源文件文件夹下创建两个(.c)源文件,以sum.c和test.c举例
/***************sum.c******************/
//全局变量 代码块之外定义的变量----全局变量
int g_val = 1010;
/**************test.c******************/
int main()
{
printf("g_val = %d\n", g_val);
return 0;
}
上面的代码,如果直接调试,编译器会报错:未声明的标识符:g_val
????我们不是在sum.c中声明了吗?怎么会这样?
因为我们没『捅破』这两个文件间的『窗户纸』
我们用一个关键字,extern,让它帮我们声明这个外部符号
/***************sum.c********************/
//全局变量 代码块之外定义的变量----全局变量
int g_val = 1010;
/***************test.c******************/
extern int g_val; //声明外部符号
int main()
{
printf("g_val = %d\n", g_val);
return 0;
}
输出结果:
这是全局变量的特点:它的作用域是整个工程,想使用时,用 extern 声明一下就可以了
如果我们用static修饰这个全局变量,会怎么样呢?
/***********************sum.c****************************/
static int g_val = 1010; //用static修饰这个全局变量
/**********************test.c****************************/
extern int g_val; //声明外部符号
int main()
{
printf("g_val = %d\n", g_val);
return 0;
}
结果编译器报错:未声明的标识符:g_val
可我们明明用extern声明了啊!怎么回事呢?
分析:
static让这个全局变量只能在自己所在的源文件内部起作用,其他地方想看看不见,即使你声明,都做不到。此时这个全局变量只能在sum.c中使用,在test.c中想看都看不见了
static修饰全局变量的作用:改变了全局变量的作用域,使得这个被修饰的全局变量只能在自己所在的源文件内部被使用,全局变量的生命周期还是整个工程的生命周期,
3. static 修饰函数 改变函数的链接属性
我们还是在同一个文件夹下建立两个(.c)源文件,以sum.c和test.c举例
/***********************sum.c****************************/
void test() //定义一个test()函数
{
printf("sum.c::test()\n"); //打印sum.c::test()
}
/***********************test.c**************************/
int main()
{
test();
return 0;
}
上面的代码,调试报错:未定义:test
实际上我们在另一个源文件中定义了
同样的方法,我们用关键字:extern,让它帮我们声明这个函数
/*************************sum.c*****************************/
void test() //定义一个test()函数
{
printf("sum.c::test()\n"); //打印sum.c::test()
}
/*************************test.c***************************/
extern void test(); //声明函数
int main()
{
test();
return 0;
}
输出结果:
说明当我们使用在同一项目文件夹下的另一个源文件中的函数时,只要想全局变量一样声明一下就可以使用了
那如果我们用static修饰这个函数,会怎么样呢?
/************************sum.c*****************************/
static void test() //定义一个test()函数,再用static修饰
{
printf("sum.c::test()\n"); //打印sum.c::test()
}
/***********************test.c****************************/
extern void test(); //声明函数
int main()
{
test();
return 0;
}
结果报错:无法解析的外部符号:_test
发现static修饰函数和修饰全局变量很相似。
static修饰函数:改变的是函数的链接属性
由外部连接属性 变成了 内部连接属性,内部连接属性就是只能在自己所在的源文件内部可以看到,其他地方想看看不见
#define 定义常量和宏
define定义标识符常量#define M 100 //注意,不加分号
int main()
{
int a = M; //M是个标识符常量
printf("%d\n", a);
return 0;
}
输出结果:
100
define定义宏 含有参数#define SQUARE(X) X*X
int main()
{
printf("%d\n", SQUARE(3)); //等同于printf("%d\n", 3*3); 替换得十分彻底
printf("%d\n", SQUARE(3+2)); //等同于printf("%d\n", 3+2*3+2); 替换得十分彻底
return 0;
}
输出结果:
9
11
发现SQUARE(3+2)并不是5*5,因为define定义的宏替换十分彻底,就是原样替换上去,如果想达到5*5的目的,可以把宏定义改为#define SQUARE(X) ((X)*(X))---最外面又加的括号是为了严谨
常见问题解答
怎样查看其他关键字的用法:
推荐一个工具:MSDN,应有尽有
有其他问题怎么办?
在评论区留言吧,我们共同进步!
感谢阅读本篇博客,如果有不错的建议或意见,欢迎在评论区留言,喜欢的话,麻烦点个赞和关注哦~~~
标签:int,sum,C语言,关键字,初识,static,test,全局变量,修饰
来源: https://blog.youkuaiyun.com/weixin_42194161/article/details/95517577