1.关键字是C 语言提供的,不能由自己创建。
2.变量名不能是关键字。
=========================================================================
auto
auto是自动的,每个局部变量都是auto修饰的。
int main()
{
auto int a = 10; //是自动创建,自动销毁的。是自动变量,一般省略。
return 0;
}
因为自动变量都是有 auto 的,所以就省略掉了。
当然 auto 在新的C语言语法中也有新的用法,这里先不做讨论。
=========================================================================
register
在 C 语言中,register是一个关键字,用于声明一个变量为寄存器变量。
寄存器变量是指要求编译器将变量存储在 CPU 的寄存器中而不是在内存中的变量。寄存器存储器的访问速度比内存快得多,这对于需要频繁访问的变量来说可以提高程序的性能。但是,由于寄存器的数量是有限制的,编译器不一定会将变量存储在寄存器中,也就是说,即使使用了register,最终变量是不是存到CPU都是由电脑自己决定。它可能会忽略 register 关键字。因此 register 关键字并不一定会提高程序的性能,而且在现代编译器中也可能已经被优化掉了。
register int x;
这将声明一个整数变量 x,要求编译器将其存储在 CPU 的寄存器中。注意,使用 register 关键字并不会影响变量的作用域或存储类型,它只是一个提示编译器将该变量存储在寄存器中的建议。
=========================================================================
typedef
在 C 语言中, typedef 是一个关键字,用于定义不同的数据类型名称。typedef 可以帮助程序员改善程序的可读性,并简化代码。使用 typedef 可以将一个现有数据类型定义为一个新的数据类型,并为该新类型指定一个名称,例如:
typedef unsigned long ulong;
以上代码将 unsigned long 定义为 uling 数据类型。这意味着在程序中可以使用 ulong 来代替 unsigned long,例如:
ulong x;
上面的代码等同于:
unsigned long x;
=========================================================================
static
static修饰局部变量
#include<stdio.h>
void test()
{
int a = 0;
a++;
printf("%d",a);
}
int main()
{
int i = 0;
while (i<10)
{
test();
i++;
}
return 0;
}
在这段函数中,从主函数 int main() 进入,变量 i=0,符合 i<0 进入 while 循环。
在 while 循环中首先进入 test 函数中。
在函数中a初始值为0,随后 a++ 变为 1 接着打印得到 1 后离开函数。
i++后仍然小于10,接着循环,直至 i=10 ,代码结束。
最终得到打印的结果是 2222222222
而当我们加入static关键字发生一些改变,结果会截然不同。
#include<stdio.h>
void test()
{
static int a = 0;
a++;
printf("%d",a);
}
int main()
{
int i = 0;
while (i<10)
{
test();
i++;
}
return 0;
}
这时的输出结果就会变为 2 3 4 5 6 7 8 9 10 11 。
结果不同的关键原因在于 static 对于局部变量的修饰,他改变了局部变量的生命周期,使得在代码走出函数后,函数中的变量a没有被销毁而保留了下来,等到下一次循环再次进入函数时以上次循环留下的a的值再次运算。
而他的本质是改变了变量的存储类型。
数据的存储类型分为栈区、堆区和静态区。
栈区中存储的是局部变量和函数的参数,堆区是静态内存分配的,静态区是全局变量和static修饰的静态变量。
---------------------------------------------------------------------------------------------------------------------------------
static修饰全局变量
在C/C++中,使用静态关键字static修饰全局变量时,它的作用域仅限于定义该变量的源文件,也就是说,其它源文件无法访问该变量,从而避免了命名冲突问题。
此外,静态全局变量的存储类别为静态存储类别,其生命周期与整个程序执行期间相同,在程序一开始就会被初始化为0或NULL,只会被初始化一次,不会被销毁,在程序结束后才会被释放。因此,使用静态全局变量可以在整个程序执行期间有效保存该变量的值。
例如,以下示例代码定义了一个静态全局变量count:
// 文件 a.c
static int count = 0;
在另一个源文件b.c中,无法访问变量count,会编译报错:
// 文件 b.c
void func()
{
count++; // 编译报错: 未声明的标识符
}
全局变量在其他源文件内部可以被使用,是因为全局变量具有外部链接属性。
但是被 static 修饰后,就变成了内部链接属性,其他源文件就不能链接到这个静态的局部变量了。
---------------------------------------------------------------------------------------------------------------------------------
static修饰函数
//文件 add.c
static int Add(int x,int y)
{
return x + y;
}
//文件test.c
#include<stdio.h>
extern int Add(int x,int y);
int main()
{
int a = 10;
int b = 20;
int sum = Add(a,b);
printf("sum = %d\n",sum);
return 0;
}
//无法解析的外部符号
static 修饰函数,使得函数只能在自己所在的源文件内部使用,不能在其他源文件内部使用。
本质上 static 是将函数的外部链接属性变成了内部链接属性,和 static 修饰全局变量一样。
=========================================================================
extern
例如,我们在 文件a.c 中声明了一个变量x为 extern 类型:
// a.c文件中
extern int x;
这里的 extern 关键字告诉编译器,变量x在本文件中只是声明,它的定义在其他文件中,需要在程序链接时进行链接。
在文件 b.c 中,定义了变量x:
// b.c文件中
int x = 10;
此时,变量x的定义已经出现在了程序中。在最终链接过程中,编译器会将 a.c 和 b.c 两个源文件中的符号都进行统一的链接,从而使得 a.c 中声明的 extern 类型的变量x能够与 b.c 中定义的变量x建立起联系,完成变量的定义。
=========================================================================
C语言中还有很多其他关键字,如变量的各种类型 int char 等等,也有一些 break continue 等关键字会放到循环中一并讲解。