深入理解符号

1.注释

注释应当准确、易懂,防止有二义性。错误的注释不但无益反而有害。

当代码比较长,特别是有多重嵌套时,应当在一些段落的结束处加注释,便于阅读

数值的单位一定要注释。

对一系列的数字编号给出注释,尤其在编写底层驱动程序的时候(比如管脚 编号)

#include <stdio.h>
#include <windows.h>
int main()
{
int /* */ i; //正确
char *s = "abcdefgh //hijklmn"; //正确
//Is it a\
valid comment? //正确
in/* */t j; //报错
system("pause");
return 0;
}

//C风格注释无法嵌套

/*总是与离它最近的*/匹配

2.接续符和转义符

转义的本质含义是:字面转特殊,或者特殊转字面

#include <stdio.h>
#include <windows.h>
int main()
{
int a = 1;
int b = 2;
int c = 3;
//试试在\之后带上空格,行不行?
//试试在\之前带上空格,行不行?
//建议:不要带

if (a == 1 &&\
b == 2 &&\
c == 3){
printf("hello world!\n");
}
#include <stdio.h>
#include <windows.h>
int main()
{
//printf("\""); //特殊转字面
printf("h\tello b\nit!\n"); //字面转特殊
system("pause");
return 0;
}
/r回到首行第一个位置
int main()
{
int i = 10;
while (i >= 0){
Sleep(1000);
printf("%2d\r", i--);
}
printf("\n倒计时结束!\n");
system("pause");
return 0;

3.单引号和双引号

//单引号是字符,双引号是字符

//C99标准的规定,'a'叫做整型字符常量(integer character constant),被看成是int型

printf("%d\n", sizeof('1'));  //结果为4,不同编译器下结果不同

char c = '1';                          //发生了截断

printf("%d\n", sizeof(c));       //结果为1

int main()
{char a='sdfg';//最多放4个字符
printf("%c",a);//结果为g,
return 0;
}

4.

//先看现象
#include <stdio.h>
#include <windows.h>
int main()
{
char c = 0;
printf("sizeof(c): %d\n", sizeof(c)); //1
printf("sizeof(c): %d\n", sizeof(~c)); //4
printf("sizeof(c): %d\n", sizeof(c << 1)); //4
printf("sizeof(c): %d\n", sizeof(c >> 1)); //4
system("pause");
return 0;
}



//是算术右移,还是逻辑右移?最高位补0,为何?
unsigned int d = -1;
printf("%d\n", d >> 1);
printf("%d\n", d >> 2);
printf("%d\n", d >> 3);
system("pause");


结论:
左移,无脑补0
右移,先判定是算术右移还是逻辑右移,判定依据:看自身类型,和变量的内容无关。

无论任何位运算符,目标都是要计算机进行计算的,而计算机中只有CPU具有运算能力(先这样简单理解),但计算的数据, 都在内存中。故,计算之前(无论任何运算),都必须将数据从内存拿到CPU中,拿到CPU哪里呢?毫无疑问,在CPU 寄存器 中。 而寄存器本身,随着计算机位数的不同,寄存器的位数也不同。一般,在32位下,寄存器的位数是32位。 可是,你的char类型数据,只有8比特位。读到寄存器中,只能填补低8位,那么高24位呢? 就需要进行“整形提升”。

<<(左移): 最高位丢弃,最低位补零

>(右移): 1. 无符号数:最低位丢弃,最高位补零[逻辑右移]

                 2. 有符号数:最低位丢弃,最高位补符号位[算术右移]

丢弃的理解:基本理解链: > 都是计算,都要在CPU中进行,可是参与移动的变量,是在内存中的。 所以需要先把数据移动到CPU内寄存器中,在进行移动。 那么,在实际移动的过程中,是在寄存器中进行的,即大小固定的单位内。那么,左移右移一定会有位置跑到"外边"的情况

a << 1; //没有影响a本身的值,未对a进行赋值

逻辑运算符

&&:级联两个(多个)逻辑表达式,必须同时为真,结果才为真 ,与&(按位与)是不同的概念

||:级联两个(多个)逻辑表达式,必须至少一个为真,结果才为真 ,与|(按位或)是不同的概念

位运算

#define SETBIT(x, n) ((x) |= (1<<(n-1))) //指定比特位置为1
void ShowBits(int x)
{
int num = sizeof(x)* 8 - 1;
while (num >= 0){
if (x & (1<<num)){
printf("1 ");
}
else{
printf("0 ");
}
num--;
}
printf("\n");
}




int main()
{
int x = 0;
SETBIT(x, 5);
ShowBits(x);
system("pause");
return 0;
}
//demo2
#include <stdio.h>
#include <windows.h>
#define CLRBIT(x, n) ((x) &= (~(1<<(n-1)))) //将指定比特位置零
void ShowBits(int x)
{
int num = sizeof(x)* 8 - 1;
while (num >= 0){
if (x & (1<<num)){
printf("1 ");
}
else{
printf("0 ");
}
num--;
}
printf("\n");
}
int main()
{
int x = 0xFF;
CLRBIT(x, 7);
ShowBits(x);
system("pause");
return 0;
}

printf("%d\n", 0x01 << 2 + 3);//+的优先级更高

#include <stdio.h>
#include <windows.h>
#define SETBIT(x, n) ((x) |= (1<<(n-1))) //指定比特位置为1
void ShowBits(int x)
{
int num = sizeof(x)* 8 - 1;
while (num >= 0){
if (x & (1<<num)){
printf("1 ");
}
else{
printf("0 ");
}
num--;
}
printf("\n");
}
int main()
{
int x = 0;
SETBIT(x, 5);
ShowBits(x);
system("pause");
return 0;
}

#include <stdio.h>
#include <windows.h>
#define CLRBIT(x, n) ((x) &= (~(1<<(n-1)))) //将指定比特位置零
void ShowBits(int x)
{
int num = sizeof(x)* 8 - 1;
while (num >= 0){
if (x & (1<<num)){
printf("1 ");
}
else{
printf("0 ");
}
num--;
}
printf("\n");
}
int main()
{
int x = 0xFF;
CLRBIT(x, 7);
ShowBits(x);
system("pause");
return 0;
} 

5.符号

1.关于取整

#include <stdio.h>
#include <windows.h>
int main()
{
//本质是向0取整
int i = -2.9;
int j = 2.9;
printf("%d\n", i); //结果是:-2
printf("%d\n", j); //结果是:2
system("pause");
return 0;
}

floor函数:本质是向负无穷大取整

ceil函数:本质是向正无穷大取整

round:本质是四舍五入

结论:浮点数(整数/整数),是有很多的取整方式的。

2.取模

取模概念: 如果a和d是两个自然数,d非零,可以证明存在两个唯一的整数 q 和 r,满足 a = q*d + r 且0 ≤ r < d。其中,q 被称为商,r 被称为余数。

#include <stdio.h>
#include <windows.h>
int main()
{
int a = -10;
int d = 3;
//printf("%d\n", a/d); //C语言中是-3,很好理解
printf("%d\n", a%d);   //c语言中是-1
system("pause");
return 0;
}


[whb@VM-0-3-centos code]$ gcc test.c
[whb@VM-0-3-centos code]$ ./a.out
-1
C:\Users\whb>python --version
Python 3.7.3
C:\Users\whb>python
Python 3.7.3 (v3.7.3:ef4ec6ed12, Mar 25 2019, 22:22:05) [MSC v.1916 64 bit (AMD64)] on
win32
Type "help", "copyright", "credits" or "license" for more information.
>>> print(-10%3)
2
>>>

在不同语言,同一个计算表达式,负数“取模”结果是不同的。我们可以称之为分别叫做正余数 和 负余数。

结论:具体余数r的大小,本质是取决于商q的。 而商,又取决谁呢?取决于除法计算的时候,取整规则。

本质 1 取整:

取余:尽可能让商,进行向0取整。

取模:尽可能让商,向-∞方向取整。

故: C中%,本质其实是取余。 Python中%,本质其实是取模

对任何一个大于0的数,对其进行0向取整和-∞取整,取整方向是一致的。故取模等价于取余 对任何一个小于0的数,对其进行0向取整和-∞取整,取整方向是相反的。故取模不等价于取余 同符号数据相除,得到的商,一定是正数(正数vs正整数),即大于0! 故,在对其商进行取整的时候,取模等价于取余。 本质 2 符号: 参与取余的两个数据,如果同符号,取模等价于取余

如果参与运算的数据,不同符号呢?

int main()
{
printf("%d\n", -10 / 3); //结果:-3
printf("%d\n\n", -10 % 3); //结果:-1 为什么? -10=(-3)*3+(-1)
printf("%d\n", 10 / -3); //结果:-3
printf("%d\n\n", 10 % -3); //结果:1 为什么?10=(-3)*(-3)+1
system("pause");
return 0;
}


>>> print(-10//3)
-4
>>> print(10//-3)
-4
>>> print(-10%3)
2
>>> print(10%-3)
-2

结论:要看取整规则,如果参与取余的两个数据符号不同,在C语言中(或者其他采用向0取整的语言如:C++,Java),余数符号,与被除数 相同。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值