c语言深度解剖(关键字)

文章目录

    • 整形在内存中的存储
    • 原反补
    • 大小端
    • 变量的存入与取出
    • char的取值范围
    • bool,float与0比较
    • 强制类型转换的理解
    • break&&continue
    • void
    • return
    • const
    • volatile
    • struct
    • union
    • enum
    • typedef

整形在内存中的存储

原反补

创建变量首先要在内存中开辟空间,开辟空间的大小由数据类型决定,在空间中存储的是二进制序列。

比如整形,32bit,32个二进制数,最高位是符号位,1表示负数,0表示整数。剩下的是有效数字位,用来表示数据。

有符号数有三种表示方法,原码,反码,补码。正数原反补相同,负数的原反补要转化。

无符号数不需要转化,直接解析。

大小端

地址的最小单位是字节,数据在内存的二进制序列按照字节划分,有高权值位与低权值位之分。

将低权值位存储到低地址处的方式为小端存储,反之为大端。

变量的存入与取出

数据首先转换成补码,不论数据类型有无符号,转换后存储到空间中
读取数据时,先区别大小端,再看数据类型,解析数据。无符号直接解析,有符号需要转换。

char的取值范围

最高位是符号位,char有8个bit位,剩下7个bit,能存储的数值范围在2的7次方-1,正负之间。但char的数据范围是-128~127。

-128是怎么表示的,由于没有-0这个概念,1000 0000这个数可以用来表示其它数字,-128的补码是1 1000 0000,将其截断后储存char中。所以,计算机在看到1000 0000这样的数时,会将其解析成-128。
c语言深度解剖(关键字)_第1张图片
无符号数数据范围0~2的n次方-1
有符号数数据范围-2的n-1次方~2的n-1次方-1
c语言深度解剖(关键字)_第2张图片

//code1
#include 
#include 
int main()
{
	char a[1000];
	int i;
	for (i = 0; i < 1000; i++)
	{
		a[i] = -1 - i;
	}
	printf("%d", strlen(a)); 
	return 0;
}
//对-128-1得到的数是127
//code2
#include 
#include 
int main()
{
	int i = -20;
	unsigned int j = 10;
	printf("%d\n", i + j);
}
//数据在内存中只是二进制序列,其表示的含义要看用什么解析
//code3
#include 
#include 
int main()
{
	unsigned int i;
	for (i = 0; i >= 0; i++) {
		printf("%u\n", i);
	}
	system("pause");
	return 0;
}

bool,float与0比较

在c中语句是用;隔开的句子。表达式是用操作符连接起来的一个句子。

c99中有布尔类型,需要引头文件stdbool

在if语句中,整形与0比较时,可以不写==,直接写变量名,根据需求加上!

float类型比较特殊,计算机不能准确的表示一个小数
c语言深度解剖(关键字)_第3张图片
有点离谱。当判断一个小数与另一个数是否相等,用它们两者之差的绝对值是否小于一个很小的数。

引float这个头文件,DBL_EPSILON,FLT_EPSILON两个精度。

强制类型转换的理解

强转没有改变数据,只是改变了数据类型,没有改变其数据。就好比改变了对一个人的看法,但那个人并没有变。

而真正的转换应该是改变了内存中的数据。

break&&continue

break跳出整个循环,continue在while&&do while中跳转到循环条件判断部分,for循环跳转到循环条件调整部分

void

void不能用来定义变量,在vs中void的大小为0字节,Linux中为1字节。但其只是一个占位符,编译器不允许其定义变量。

1.void作为函数返回值作为占位符,告知编译器这个函数不用返回值,不能接受其返回值,直接报错
2.作为形参,告知用户与编译器该函数不用传参
3.void* 可以接受任何类型的指针,任何类型的指针可以接受void*
所以c语言中void*常用来设计一个函数的接口,比较通用

return

删除的本质是什么,为什么删除文件总是很快,下载文件很慢。删除其实只是标识该数据无效,并没有将数据置0/1。c语言深度解剖(关键字)_第4张图片
不能返回局部变量的地址。printf也是函数,创建函数栈帧时将存储局部变量的空间设置成随机值,打印出来的乱码。

函数中的return是将数据放到一个寄存器中,所以能返回一个局部变量。即使销毁局部变量,寄存器还保存着数据。

const

const修饰的变量,不能被直接修改。就是说能被间接修改。

意义:告知编译器该变量不能被修改,做相关检查。
告知程序员该变量不能被修改,一种自描述。
c语言深度解剖(关键字)_第5张图片
字符串常量是不能被修改的,这是系统规定,真正的不能修改。

任何函数参数都要创建临时变量,包括指针变量。

volatile

该关键字修饰的变量,使系统不做任何优化,以防止程序出现错误。

struct

空结构体的大小不同编译器不一样,vs不允许定义空结构体,Linux的空结构体大小为

柔性数组,结构体中最后一个成员为数组,大小为0,arr[0],arr[]。然后用动态内存开辟,申请空间。结构体大小不会将数组算在内,sizeof(struct data) + 10 * sizeof(int),多申请的空间是给柔性数组使用的。

栈区向下增长,堆区向上增长。但是所有的变量都是从低地址开始使用的。

只能在初始化时对结构体赋值,之后不允许赋值,就像数组一样。

union

所有成员的地址一样,成员的地址都在低地址处,每个元素都是第一个元素。

用union能判断机器的大小端,
c语言深度解剖(关键字)_第6张图片

enum

枚举能很好的表示一系列相关的常量,定义枚举常量能更好的反应变量的意思。

typedef

类型的重定义

int* a,b;

a为指针,b为整形。

typedef int* int_p;
int_p a,b;//两者都是指针。

c语言深度解剖(关键字)_第7张图片
定义变量时,存储类型关键字只能出现一个,所以不存在

typedef static int s_int;

你可能感兴趣的:(【C语言】学习总结,c语言,开发语言,后端)