C深剖关键字(2)

目录

一:signed / unsigned关键字

二:switch关键字

三:break / continue关键字

四:goto关键字


一:signed / unsigned关键字

在正式了解signed / unsigned关键字之前,我们需要对数据在所开辟内存中到底是如何存储进行一个深入了解。 首先就要了解:

整数的二进制表示有3种表示形式:原码----反码----补码

而内存存储的是二进制的补码!
整数:正数 / 负数
 正数:原码反码补码相同
 负数:原码:按照一个数的正,负直接写出来的二进制就是原码
            反码:符号位不变,其他位按位取反
            补码:反码的二进制序列+1,就是补码
符号位为0,正数,为1,负数
15:
00000000000000000000000000001111   ----->原码-反码-补码    最高位为符号位0,正数
 -15:
//10000000000000000000000000001111   ----->原码
//11111111111111111111111111110000   ----->反码
//11111111111111111111111111110001   ----->补码

10
00000000000000000000000000001010  原码反码补码相同
4个二进制转化为一个16进制
 0   0   0   0   0   0   0   1
-10
10000000000000000000000000001010  原码
11111111111111111111111111110101  反码
11111111111111111111111111110110  补码
4个二进制转化为一个16进制
 f   f   f   f   f   f   f    6

为什么内存存储的是二进制的补码呢
计算机只有加法器

如 1+(-1)=0
若采用原码相加:
 00000000000000000000000000000001   1的原码
 10000000000000000000000000000001   -1的原码
 ---------------------------------  相加
 10000000000000000000000000000010 ----> -2 err
若采用补码相加:
 00000000000000000000000000000001   1的补码
 11111111111111111111111111111111   -1的补码
 ---------------------------------  相加
100000000000000000000000000000000 ----> 0 right
原码到补码,补码到补码:
  1
 法一:
 10000000000000000000000000000001  原码
                取反
 11111111111111111111111111111110  反码
                加1
 11111111111111111111111111111111  补码
                减1
 11111111111111111111111111111110  反码
                取反
 10000000000000000000000000000001  原码
法二:
 10000000000000000000000000000001  原码
                取反
 11111111111111111111111111111110  反码
                加1
 11111111111111111111111111111111  补码
                取反
 10000000000000000000000000000000  
                加1
 10000000000000000000000000000001  原码
综上所述: 
原码取反+1得到补码,补码再取反+1得到原码

正如我们实际定义一个无符号数如下:

#include<stdio.h>
int main()
{
	unsigned int b = -10;
	printf("%d\n", b); // -10
	printf("%u\n", b); // 4294967286
	return 0;
}

解析:

我们在此代码中定义了一个无符号数b=-10的变量,

数据要先存再取,存补码,取原码

我们都清楚内存存储的是补码

-10
10000000000000000000000000001010  原码
11111111111111111111111111110101  反码
11111111111111111111111111110110  补码

当用%d的形式输出时,此时就将其看成是一个有符号数,将上述补码转换为原码即为-10

当用%u的形式输出时,才是正儿八经的无符号数,而无符号数的最高位就不再是符号位,此时原码反码补码相同,将上述二进制补码转换为十进制就是一个超大的数字4294967286

二:switch关键字

基本语法结构:

switch (整型变量 / 常量 / 整型表达式) 
{
case var1:
	break;
case var2:
	break;
case var3:
	break;
default:
	break;
}

注意:

// // 任何具有判定能力的语法结构,都必须具备:判定+分支

// //case本身是用来判定的

// //break用来进行分支功能

#include<stdio.h>
int main()
{
	int day = 0;
    while (1)
	{
	    scanf("%d", &day);
		switch (day)  // 整型||整形表达式||常量
		{
		case 1:  // case本身是用来判定的
			printf("星期1\n");
			break; //break用来进行分支功能
		case 2:
			printf("星期2\n");
			break;
		default:
			printf("请输入正确的数字\n");
			break;
		}
	}

若要一个case执行多条语句:

可以在其中一条case语句后多输出相关语句

		case 3:
			printf("星期3\n");
			printf("星期3\n");
			printf("星期3\n");
			printf("星期3\n");
			printf("星期3\n");
			break;

但是,如果我们在case后定义一个变量并且需要访问它时,如下:

不难发现,编译器出错 ,但是当我们在整个case3后面加一个花括号呢

此时编译器是可以正常运行的 ,当然,想要执行上述操作,我们最建议的还是创造函数来解决:

 如果想要多条case执行一条语句时:

#include<stdio.h>
int main()
{
	int day = 0;
	while (1)
	{
		scanf("%d", &day);
		switch (day)  // 整型||整形表达式
		{
		case 1:  
		case 2:
		case 3:
		case 4:
		case 5:
			printf("周内\n");
			break;
		case 6:
		case 7:
			printf("周末\n");
			break;
		default:
			printf("请输入正确的数字\n");
			break;
		}
	}
	return 0;
}

 注意:case 后面不能直接跟变量,但可以用宏定义变量即为常变量,default语句的位置可以放在任意位置。

#include<stdio.h>
#define A 10
int main()
{
	const int a = 10;
	switch (a)
	{
	//case 10:
	//case a: err
	//case 后面不能直接跟变量,但可以用宏定义变量即为常变量
	case A:
		printf("hello bit!\n");
		break;
	default :
		break;
	}
	return 0;
}

总结:

1.switch语法结构中,case完成的判定功能,break完成的分支功能,default处理异常情况

2.case:执行语句==1:n,case多条语句(不能定义变量,如果需要,{},函数) break

3.case:执行语句= =n:1,多条case后续不写break

4.default:可以出现在任何地方,推荐放在结尾

5.case:不能:const,普通的变量,建议要有好的布局case的方式

三:break / continue关键字

while

先看一段代码(break)

 我们不难发现break的作用就是跳出循环,当把break换成continue时

 continue的作用就是结束本次(一次)循环,既然是结束本次循环,所以此时continue跳到while条件判定那进行循环

do while

先看一段伪代码

	do {
		printf("hello\n");
		if (flag)
		{
			continue;
		}
	} while (cond);

在do while中,使用continue,continue会跳到哪呢?

条件判断在哪里,continue就跳转到哪里,所以continue跳转到while(cond)条件判断那

for

再看一段伪代码

在for循环中,使用continue,continue会跳到哪呢?

此时我们不难发现 ,for循环的continue会跳转到条件更新处i++

总结:

while循环 do while循环用continue都是到条件判定处

for 循环是到条件更新处

四:goto关键字

看代码:

向下跳转:

#include<stdio.h>
int main()
{
	goto end;
	printf("hello 1\n");
	printf("hello 2\n");
	printf("hello 3\n");
	end: // 标签
	printf("hello 4\n");  // hello 4
	printf("hello 5\n");  // hello 5
	printf("hello 6\n");  // hello 6
	return 0;
}

向上跳转:

#include<stdio.h>
int main()
{
    end: // 标签
	printf("hello 1\n");
	printf("hello 2\n");
	printf("hello 3\n");
	goto end;  
	printf("hello 4\n");  
	printf("hello 5\n");  
	printf("hello 6\n"); 
	// 死循环
	// goto语句在代码块中可以跳转
	return 0;
}

案例:

#include<stdio.h>
int main()
{
	int i = 0;
start:
	printf("[%d] goto running...\n", i);
	i++;
	if (i < 3)
	{
		goto start;
	}
	printf("goto end...\n");
	return 0;
}

 goto语句只能在本代码块内使用,不能跨文件和使用函数访问!!!

总结:

//很多公司确实禁止使用goto,不过,这个问题我们还是灵活对待,goto在解决很多问题是有奇效的。

//我们可以认为goto使用场景较少,一般不使用。但是必须得知道goto,需要的时候,也必须会用

猜你喜欢

转载自blog.csdn.net/bit_zyx/article/details/122256900