C语言关键字解析

在C语言中有32个关键字,如下表所示:
这里写图片描述
释:
(1)声明:
1)告诉编译器,这个名字已经匹配到一块内存上;
2)告诉编译器,这个名字已经预定了,其他地方再也不能用它来作为变量名或对象名。
(2)定义:
编译器创建一个对象,为这个对象分配一块内存空间,并给它取上名字,这个名字就是我们经常所说的变量名或者对象名。
(3)声明和定义的区别:
1)声明可以出现多次,但是定义只能一次。
2)定义创建了对象,并为对象分配内存,但是声明只是匹配了一块内存,并没有分配内存。

为了方便记忆,将关键字分成几类:
第一类,有关数据“模子”的关键字:void、char、short、int、long、float、double、sizeof;
第二类,有关数据符号的关键字:signed、unsigned;
第三类,构造类型:struct、union、enum、typedef;
第四类,有关存储与生命周期的类型:auto、static、extern、register、const、volatile;
第五类,有关语句的类型:if、else、for、while、do、switch、case、fault、goto、break、continue、return

以下,将主要介绍sizeof、typedef、register、signed和unsigned、volatile、static等关键字。

1、register——最快的关键字
(1)说明:这个关键字请求编译器尽可能的将变量存放在CPU内部的寄存器中,而不是通过内存寻址访问以提高效率(是尽可能,不是绝对)。
(2)解释:寄存器其实就是一块一块小的存储空间,只不过其存储速度比内存快得多,但是价格昂贵。
(3)注意:
1)register变量必须是一个单个的值,并且其长度必须小于或等于整形的长度。
2)register变量可能不存在内存中,所以不能用取地址运算符“&”来获取register变量的地址。

2、static——最名不符实的关键字
(1)说明:声明静态变量。
(2)作用:
1)修饰变量:static可以修饰局部变量和全局变量,它们都存放在内部的静态区中。
A、静态全局变量:作用域仅限于变量被定义的文件中,其他文件即使使用extern声明也不能使用它。准确的说:作用域是从定义之处开始到文件结束。在定义之处前面的那些代码行也不能使用它,想要使用就得在前面再加extern***。
B、静态局部变量:作用域仅限于该函数里,该文件中的其他函数也用不了。虽然局部变量的生命周期随着函数的结束而终止,但是因为被static修饰的变量总是存在内存的静态区,所以即使这个函数运行结束,这个静态变量的值也不会被销毁,函数下次使用时仍然能用到这个值。
【例1】

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>

static int i = 0;

void func1()
{
	i = 0;
	i++;
}

void func2()
{
	static int j = 0;
	j++;
}

int main()
{
	int k = 0;
	for (k = 0; k < 10; k++)
	{
		func1();
		func2();
	}
	system("pause");
	return 0;
}

运行结果:
在这里插入图片描述

释:
a、每次调用func1函数时,i(静态全局变量)都被强制置0, 所以i等于1。
b、虽然调用func2函数10次,但是“static int j = 0”语句只被执行了一次,所以j等于10。

2)修饰函数:函数前面加static使得函数成为静态函数,表示该函数的作用域仅限于本文件。好处是:不同的人编写不同函数时不用担心自己定义的函数是否会与其他文件中的函数同名。

3、符号关键字——unsigned和signed
(1)说明:最高位如果是1,表明这个数是负数,其值为除最高位以外的剩余位的值加上“-”号;最高位如果是0,表明这个数是正数,其值为除最高位以外的剩余位的值。
【例2】signed char
0000 0001表示1;1000 0001表示-1。
8位的char类型数,其值表示的范围为:-27—(27-1)。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

int main()
{
	signed char a[1000];
	int i;
	for (i = 0; i < 1000; i++)
	{
		a[i] = -1 - i;
	}
	printf("% d\n", strlen(a));
	system("pause");
	return 0;
}

答案是:255。
释:计算机系统中,数值以补码的方式来存储。因为用补码可以将符号位和其他位统一处理,并且减法和加法都可以用补码来处理,当最高位(符号位)有进位时,进位将被舍弃。并且,strlen遇“\0”则终止。

注意:单纯的char类型应该只用于字符值得存储和使用;有符号和无符号的char类型变量只能用于数值的存储和使用。

4、const
(1)说明:const是constant的缩写,表示恒古不变。被const修饰的变量称为常变量,准确来说应该是只读的变量。
(2)作用:
1)修饰只读变量:定义const只读变量,具有不可变性。
A、const int Max = 100;
释:const修饰的只读变量必须在定义的同时初始化,因为定义后就不能再被改变了。
B、int Array[Max];
释:这样编译时会报错,数组下标只能是常量,即使常变量也不可以,但是宏常数可以。
【问题1】case语句修饰的只读变量必须在定义的同时初始化,为什么?
答:因为case后面只能是常量、字符型常量和常量表达式。
2)修饰数组
3)修饰指针
【例3】p可变,p指向的对象不可变

int const *p;//p可变,p指向的对象不可变
int* const p;//p不可变,p指向的对象可变
const int* const p;//p不可变,p指向的对象也不可变

4)修饰函数的参数和返回值

5、volatile—最易变的关键字
(1)说明:volatile是易变、不稳定的意思。
(2)作用:用volatile修饰的变量可以被某些编译器未知的因素更改,即更新数据,未知的因素如操作系统、硬件或者其他线程等。
【例4】
int i = 10;
int j = i;//1)语句
int k = i;//2)语句
分析:编译时编译器认为i的值没有发生变化,所以在1)语句时从内存中取出i的值赋给j后并没有被丢掉,在2)语句时继续用这个值给k赋值,而不生成汇编代码重新从内存里取出i的值。

【例5】
volatlie int i = 10;
int j = i;
int k = i;
分析:例2与例1不同的是,volatile关键字告诉编译器,i的值随时可能发生变化,则每次用i,编译器都会生成汇编代码从内存中取i的值。

【问题2】const volatile int i = 10;这行代码有没有问题?如果没有,那么i到底是什么属性?
答:没有问题。因为const表示常量语义,被const修饰的对象在所在的作用域里无法进行修改;volatile表示易变的,即在运行期对象可能在当前程序上下文的控制流以外被修改。发生易变的情况,如:在多线程中。被其他线程修改;对象所在的存储器可能被多个硬件设备随机修改等情况。例如,只读的状态寄存器,它是volatile属性,因为它可能被意外的修改。但是,同时它也具有const属性,因为它修饰的内容只能被读而不能被写。可知:它们控制的范围不同,被const修饰的对象在程序本身内不能修改,而被volatile修饰的对象可能在本程序外被修改。所以,const和volatile一起使用没有问题。

6、sizeof——最冤枉的关键字
(1)说明:sizeof是关键字不是函数,用于计算对象的所占的内存大小。
【例6】sizeof是关键字不是函数
int i = 0;
(A)sizeof(int); (B)sizeof(i); (C)sizeof int; (D)sizeof i;
结果是:在32位系统下,A、B、D的值都为4,而C编译出错。
释:sizeof是关键字,带不带括号都可以,但是在int前面可以加unsigned和signed,不可以加sizeof。

【例7】计算以形参传递整个数组时的大小

int b[100];
void fun(int b[100])
{
sizeof(b);
}

结果是:sizeof(b)等于4,即一个元素的大小。
释:数组当形参时,不能将整个数组传值,只能传单个元素。

【例7】有关数组和指针占内存空间大小的计算
1)int *p = NULL;
sizeof§的值是什么?sizeof(*p)的值又是多少?
答:都是4个字节。
2)int a[100];
sizeof(a)的值是多少?//400
sizeof(a[100])呢?//4,因为sizeof只计算,不访问
sizeof(&a)呢?//4
sizeof(&a[0])呢?//4

更多关于sizeof的计算,请访问博客——“计算对象所占的内存大小

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值