栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

补充C语言01:关键字

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

补充C语言01:关键字

关键字

C 语言一共多少个关键字呢?一般的书上,都是 32 个 , 但是这个都是 C90(C89) 的标准。其实 C99 后又新增了5 个关键字。不过,目前主流的编译器,对 C99 支持的并不好,后面默认情况,使用 C90 ,即认为 32个关键字

关键字-auto 如何使用:

一般在代码块中定义的变量,即局部变量,默认都是auto修饰的,不过一般省略,

#define _CRT_SECURE_NO_WARNINGS 1
#include 
int main()
{
	for (int i = 0; i < 10; i++)
	{
		printf("i=%dn", i);
		if (1)
		{
			auto int j = 0;
			//自动变量 
			printf("before: j=%dn", j);
			j += 1;
			printf("after : j=%dn", j);
		}
	}
	return 0;
}

 auto关键字已经很老,基本永不使用。

 关键字-register

距离CPU越近的存储硬件,速度越快。 

register会尽量将所修饰变量,放入CPU寄存区中,从而达到提高效率的目的 

注意:register修饰的变量,不能取地址(因为已经放在寄存区中了,地址是内存相关的概念)  

#define _CRT_SECURE_NO_WARNINGS 1
#include  
int main() 
{ 
	register int a = 0; 
	printf("&a = %pn", &a); 
	return 0; 
}

一般不使用register了,因为现在的编译器,已经很智能了,能够进行比人更好的代码优化。早期编译器需要人为指定register,来进行手动优化,现在不需要了

关键字-extern

extern的正确使用

 extern的错误使用

 声明并没有开辟空间,所以不能进行赋值或者初始化

extern的建议

    extern int g_val;//变量声明必须带上extern!(防止,出现不知道是声明还是定义的问题)extern void show();//函数声明建议带上extern!

关键字-static

结论:

    static修饰全局变量,该变量只在本文件内被访问,不能被外部其他文件直接访问static修饰函数,该函数只在本文件内被访问,不能被外部其他文件直接访问static修饰局部变量,更改局部变量的生命周期,将其放在静态区

 注意这个不是内存,而是操作系统中的进程地址空间

补充:全局变量和函数都可以跨文件使用,而跨文件使用又是为了做大型项目的时候方便交互

关键字-sizeof
#define _CRT_SECURE_NO_WARNINGS 1
#include
int main()
{
	int a = 10;
	printf("%d ", sizeof(a));
	printf("%d ", sizeof a );
	printf("%d ", sizeof(10));
	printf("%d ", sizeof 10 );
	printf("%d ", sizeof(int));
	printf("%d ", sizeof int);
	return 0;
}

运行后发现最后一个printf报错,sizeof int是错的注意sizeof这个关键字返回的是无符号的

编码好习惯:如果要定义全局变量,那么在前面加上g_

比如: 全局变量g_val

深入理解变量内容的存入和取出
signed int b = - 10 ;
-10存入:

-10的原码:1000 0000 0000 0000 0000 0000 0000 1010-10的补码:1111 1111 1111 1111 1111 1111 1111 0101-10的补码:1111 1111 1111 1111 1111 1111 1111 0110

-10取出:

 1000 0000 0000 0000 0000 0000 0000 1010

unsigned int d = -10; 

-10存入:

-10的原码:1000 0000 0000 0000 0000 0000 0000 1010-10的补码:1111 1111 1111 1111 1111 1111 1111 0101-10的补码:1111 1111 1111 1111 1111 1111 1111 0110

-10取出:

 1111 1111 1111 1111 1111 1111 1111 0110


 

关键在于到底是%d打印,还是%u打印

总结:

    存:字面数据必须先转成补码,再放入空间当中,所谓符号位,完全看数据本身是否携带+-         号。和变量是否有符号无关! 取:数据一定要先看变量本身类型,然后才决定要不要看最高符号位。如果不需要,直接二         进制转成十进制。如果需要,则需要转成原码,然后才能识别。( 当然,最高符号位在哪         里,又要明确大小端 )

 编码好习惯:函数名的首字母大写, 

比如:函数名My_strlen

如何理解char类型中的-128 

-128的原码:1 1000 0000

-128的反码:1 0111 1111

-128的补码:1 1000 0000

char类型只有8个bit位,所以-128存入char中的时候会发生截断

-128在char中为1000 0000,他们规定这个1000 0000就当作-128注意1000 0000和0000 0000都可以表示0

数据类型的取值范围:-2^(n-1)到2^(n-1)-1

比如char取值范围:[-128,127]就是 [-2^7,2^7-1]比如short取值范围:[-2^15,2^15-1] 比如int取值范围:[-2^31,2^31-1] 

关键字-bool(_bool)

c99之前,主要是c90是没有的,目前大部分书,都是认为没有的。因为书,一般都要落后于行业但是c99引入了_Bool类型(你没有看错,_Bool就是一个类型,不过在新增头文件stdbool.h中,被重新用宏写成了bool,为了保证C/C++兼容性)。

 

 编码好习惯

 在真假判断中,右边的代码比左边的代码更好,左边的代码会使人产生误解


关键字-double

double类型 变量与"零值"进行比较
#define _CRT_SECURE_NO_WARNINGS 1
#include
int main()
{
    double x = 1.0;
    double y = 0.1;
    printf("%.50lfn", x);
    printf("%.50lfn", y);
    if ((x - 0.9) == y) {
        printf("you can see me!n");
    }
    else {
        printf("oops!n");
    }
    return 0;
}

这个就叫做精度损失 

 解决方案:

#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
#include
int main()
{
    double x = 1.0;
    double y = 0.1;
    printf("%.50lfn", x);
    printf("%.50lfn", y);
    if (fabs((x - 0.9) - y)< DBL_EPSILON) {
        printf("you can see me!n");
    }
    else {
        printf("oops!n");
    }
    return 0;
}

 这段代码中的fabs是一个求绝对值的函数fabs((x - 0.9) - y)< DBL_EPSILON这里不能写等于,

补充:()强制类型转换,不改变内存中的数据,只改变对应的类型

switch与case关键字

 除非加上{ },不然switch和case不支持

编程好习惯:针对case:如果可以的话,把常见的指向情况放前面,把不常见的放后面

关键字-continue

 在for循环中continue是跳到,改变循环变量那里

编程好习惯:使用循环语句的时候,尽量做到外小内大,一般来说这样的话,效率会高一点

关键字-void

 

 在linux中void的大小是1,而在vs2019中void的大小是0void本身就被编译器解释为空类型,强制的不允许定义变量

补充:计算机中清空数据,只要设置该数据无效即可

为什么局部变量具有临时性
#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
char* show()
{
	char str[] = "hello bit";
	return str;
}
int main()
{
	char* s = show();
	printf("%sn", s);
	return 0;
}

具体的后面会说,但是值得注意的是printf也是一个函数,也会形成函数栈帧

关键字-return 
#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
char* show()
{
	char str[] = "hello bit";
	return str;
}
int main()
{
	char* s = show();
	printf("%sn", s);
	return 0;
}

return返回的时候,会通过寄存器的方式,返回给函数调用方,及时没有接收也一样 

变量的左右值

任何一个变量名,在不同的应用场景中,代表不同的含义!!! 

关键字-const
#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
int main()
{
	const int i = 10;
	int* p = (int*)&i;
	printf("before:%dn", i);
	*p = 20;
	printf("after:%dn", i);
	return 0;
}

 

 const修饰变量的时候,虽然不能直接修改,但是可以间接到修改,const修饰变量,更重要的意义在于告诉程序员不要修改它,char *p ="hello bit!n";   这个才是真正意义上的不可被修改


 一个严谨的类型赋给一个不严谨的类型,报错 一个不严谨的类型赋给一个严谨的类型,不报错

补充:

#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
int main()
{
	int a = 10;
	int* p = &a;
	*p = 20;
	int b = *p;
	return 0;
}

(类型相同)对指针进行解引用,就是指针指向的目标,*p就是a

关键字-volatile

这个关键字,就是不希望被编译器优化,不要CPU优化,达到稳定访问内存的目的

volatile const int a = 10;//正确

 关键字-struct

 空结构体的大小,在不同的编译器下是不同的

 关键字-typedef

上面的unsigned int32 b;等价于char int a;所以报错

补充:

存储关键字有:auto,extern,register,static,typedef存储关键字,不可以同时出现,也就是说,在一个变量定义的时候,只能有一个

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/779284.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号