山东省建设工程质量监督网站,做网站违法,互联网推广平台有哪些,咨询行业网站建设公司文章目录一.注释二.续行符与转义符1.续行符2.转义符三.回车与换行四.逻辑操作符五.位操作符和移位操作符六.前置与后置七.字符与字符串八./和%1.四种取整方式2.取模与取余的区别和联系3./两边异号的情况1.左正右负2.左负右正九.运算符的优先级一.注释
注释的两种符号#xff…
文章目录一.注释二.续行符与转义符1.续行符2.转义符三.回车与换行四.逻辑操作符五.位操作符和移位操作符六.前置与后置七.字符与字符串八./和%1.四种取整方式2.取模与取余的区别和联系3./两边异号的情况1.左正右负2.左负右正九.运算符的优先级一.注释
注释的两种符号
// 内容/*内容 */说明:/*只会与最近的 */进行匹配。
int main()
{//这是一段注释/*这是一段注释*/return 0;
}说明注释在预处理阶段准确的来说是预编译就被删除了而与之代替的是空格所以注释的本质上其实是空格。注释的意义在于提高代码的可读性。 4. 补充: 1.空格:C语言中空格是用来当做符号识别的分割符 2:预处理器识别符号的基本方式是贪心法所谓贪心指的是编译器会尽可能的识别多的字符(也就是说编译器将程序分解成符号的方法是从左到右一个字符一个字符地读入如果该字符可能组成一个符号那么就再读一个字符判断已经读入的两个字符组成的字符串是否可能是一个字符的组成部分如果可能继续读入下一个字符判断已经读入的两个字符是否可能是一个符号的组成部分如果可能继续读入下一个字符重复上述判断直到读入的字符组成的字符串已经不再可能组成一个有意义的字符)——C陷阱与缺陷,这样做是为了满足大多数的情况而少数的情况需要我们自己对符号进行分割那具体如何分割当然用空格了。
例1:
#includestdio.h
int main()
{ int a 1;int* p a;int b a/ *p;//注意这里的/*之间需加一个空格否则会被编译器判断为注释符号return 0;
}例2:
int main()
{int a 1;int b 2;int c a-- - b;//是a后置减减再减去bprintf(%d\n, c);//答案是-1a 1;b 2;c a - --b;//是b前置--然后a再减去bprintf(%d\n, c);//答案0return 0;
}说明:像这类准二义性的问题有时候会给我们带来麻烦。 不好的注释方式 例1:
#if 0
int main()
{printf(hello world\n);return 0;
}
#endif例2:
int main()
{if (0){printf(hello world\n);}return 0;
}说明:这样注释的方式并不明显所以阅读代码时并不确定这段代码是否是一段注释所以不建议这样进行注释。 二.续行符与转义符
1.续行符
逻辑表达式:
#includestdio.h
int main()
{int a 1;int b 1;int c 0;int d 1; if (a 1 \b 1 \c 0 \d 1){printf(hello world\n);}return 0;
}说明:不带续行符也是可以的但这就好像不写函数参数默认为int一样所以严格一点还是建议带上续行符号。 注意:续行符后不能带空格 字符串
int main()
{char* p abcd\
efg;//这是为了处理比较长的字符串而准备的我们这里就暂且用一下。printf(%s\n, p);//字符串的续行符是不会被打印出来的return 0;
}2.转义符 说明\在这里是改变原字符的意思具体有以上14种。 注意:单个\出现是不能被打印要想打印需把\转义也就是\\。 例1:
#include stdio.h
int main()
{printf(c:\code\test.c\n);int len strlen(c:\code\test.c\n);//这里的\是打不出来的printf(%d,len);//len是13return 0;
}解释: 1——c 2—— 3——\c(注意在vs 2019中 \加上字符被编译器认为是一个转义字符) 4——0 5——d 6——e 7——\t 8——e 9——s 10——t 11—— . 12——c 13——\n 例2
#includestdio.h
#includestring.h
int main()
{printf(%d\n,strlen(c:\\code\\test.c\\n));//这样能打印出\了但是字符的个数比前面多了3个——总共16个字符printf(c:\\code\\test.c\\n);return 0;
}效果: 例3:
#includestdio.h
int main()
{printf(\);//这里\是改变的意思而能被打印出来return 0;
}说明:会自动与最近的”进行匹配
三.回车与换行
1.回车 符号\r 说明:指的是回到当前行的首元素 2.换行 符号:\n 说明:准确的是回到当前行的下一行的相同位置 注意:一般编译器实现的换行是回车换行上面提及的换行 一个有意思的旋转光标的实现
#includestdio.h
#includeWindows.h
int main()
{while (1){printf(\\\r);Sleep(100);printf(|\r);Sleep(100);printf(-\r);Sleep(100);printf(/\r);Sleep(100);}return 0;
}四.逻辑操作符 逻辑与 说明:一假即为假全真才为真串联 逻辑或: || 说明: 一真即为真全假才为假并联 运算顺序从左向右 #includestdio.h
int my_print()
{printf(hello\n);return 1;
}
int main()
{int judge 0;scanf(%d, judge);judge my_print();//输入0时不执行my_print//输入1时执行my_print//judge || my_print();//输入1时不执行//输入0时执行return 0;
}五.位操作符和移位操作符 位运算符是对内存的数直接进行运算的(补码) 按位与 说明:同1才为1其余都为0 按位或| 说明同0才为0其余为1 按位异或^ 说明:相同为0相异为1 按位取反: ~ 说明:1变0,0变1包括符号位。 简单运用:
int main()
{printf(%d\n, 1 2);//0// 01(二进制)// 10// 00//答案是:0printf(%d\n, 1 | 2);//3// 01// 10// 11//答案:3printf(%d\n, 1 ^ 2);//3// 01//^ 10// 11//答案:3printf(%d\n, ~-1);//0// 11111111 11111111 11111111 11111111//~// 00000000 00000000 00000000 00000000//答案0return 0;
}移位操作符 1.移位操作符运算后不会影响操作数本身 2.移位操作符运算的范围为整数
左移操作符 符号(双箭头向左) 功能将补码整体左移n位舍去右边补0。
int a 1;
int b a1;//这是将a的补码向左移动一位a的补码00000000000000000000000000000001 b的补码00000000000000000000000000000010 2. 右移操作符 符号双箭头向右
1.算数右移 功能:将补码整体向右移n位最左边补符号位 例子
int a -1;
int b a1:a的补码11111111111111111111111111111111 b的补码11111111111111111111111111111111 1.逻辑右移 功能将补码整体向右移n位最左边补0 一般右移都是算数右移补符号位 关于sizeof的整形提升问题
#includestdio.h
int main()
{char a 0;printf(%d\n, sizeof(~a));//4printf(%d\n, sizeof(!a));//1printf(%d\n, sizeof(aa));//4printf(%d\n, sizeof(a|a));//4printf(%d\n, sizeof(a^a));//4printf(%d\n, sizeof(a 1));printf(%d\n, sizeof(a 1));return 0;
}说明:位运算符合移位操作符都是在整形的大小进行计算的。 注意:!a在VS下是1在Linux下是4这里我们推荐当做4进行理解。 经典运用: 1.用异或和按位与实现加法 说明:CPU也是通过异或和按位与进行加法运算的。 #includestdio.h
int main()
{int begin 0;int process 0;int end 0;scanf(%d%d, begin, end);process end;while (process)//当没有进位信息就停止循环{//先进行异或不保留进位信息end begin ^ process;//获取进位信息左移之后是进位process (begin process) 1;//更新下一轮的加数信息begin end;}printf(%d\n, end);return 0;
}2.用异或实现两个数交换
#includestdio.h
int main()
{int a 1;int b 2;printf(a%d,b%d\n, a, b);a a ^ b;b a ^ b;// b a^(b^b)a^0aa a ^ b;//a b^(a^a)b^0bprintf(a%d,b%d\n, a, b);return 0;
}说明: 1.异或支持交换律和结合律 2.0与任何数异或等于本身 3.两个相同的数异或为0 3.用按位与将二进制序列输出
void ShowBites(int x)
{for (int i 31; i 0; i--){if (((xi) 1) 1){printf(1);}else{printf(0);}}
}4.用异或将指定的数变为1
#includestdio.h
#define SPECIALBIT(x,y) ((x)|(1(y-1)))
int main()
{int a 0;SPECIALBIT(a, 5);ShowBites(a);return 0;
}5.用按位与将指定位置变为0
#includestdio.h
#define SPECIALBITS(x,y) ((x)^(1(y-1)))
int main()
{int a 0xFFFFFFFF;SPECIALBITS(a, 5);ShowBites(a);return 0;
}
六.前置与后置
我们一般说前置是先自增一再使用后置是先使用然后再加1真的是这样吗 答案:应该说大多数情况下是这样的这样只是为了方便我们记忆这种情况并不是绝对的。 满足情况的例子
int main()
{int a 0;int b 1;b a;return 0;
}ba的反汇编代码 int main()
{int a 0;int b 1;b a;return 0;
}不满足情况的例子:
int main()
{int a 0;a;a;return 0;
}一个典型的问题表达式 所谓的问题表达式并不是说表达式的语法有问题而是说表达式的计算路径具有二义性也就是有多种计算路径。 #includestdio.h
int main()
{int a 1;a (a) (a) (a);printf(%d\n, a);return 0;
}说明这里是与的计算顺序与优先级的问题 有两种可能: 1.先计算全部的也就是把a的值先自增三次再把自增过后的a相加答案为12这是VS下运行的结果 2.先计算前两个也就是先把a自增两次再把自增过后的前两个a相加最后再对a自增一再把前两次相加的结果再相加此时a自增的结果也就是33410 这是Linux下的运行结果。 七.字符与字符串
1.字符串 说明C语言并没有字符串类型但是有字符类型。 字符串在C语言中主要以两种形式存在 1.数组 2.字符指针 但是字符串应用的场景很多。 int main()
{char* p abcdef;//p是字符串首字符的地址//说明这里的字符串是不能进行修改的。char arr[]abcdef;//字符串被放在数组中字符串里面的字符是能修改的char c 0123456[1];//这是字符指针的形式。printf(%d\n,sizeof(abcdef);//这是以数组形式存在的其大小是//字符串的字符个数printf(%d\n, sizeof());//里面有一个字符\0所以是1return 0;
}2.字符 说明:字符常量是以整形存在的字符常量被放在字符变量中是要发生截断的。 注意: 1.一个字符里面最多包含4个字符‘abcd’对应4个字节 2.一个字符里面不能为空
int main()
{printf(%d\n, sizeof(c));//这是4个字节char c c;printf(%d\n, sizeof(c));//这是1个字节printf(%d\n,sizeof(c));//整形提升4个字节//CPU运算是以整形大小的return 0;
}为什么存在ASCII码表 因为代码是外国人发明的外国的字符由26个英文字符组成这也就照应了ASCII码表里面为啥有26个大小写字符那与计算机怎么交互信息呢自然是由ASCII码表翻译出的字符啦 八./和%
1.四种取整方式
1.向0取整 函数:trunc() 参数double 返回值:double #includestdio.h
#includemath.h
int main()
{printf(%f\n, trunc(5.4));//5.0return 0;
}2.向负无穷取整
#includestdio.h
#includemath.h
int main()
{printf(%f\n, floor(5.4));//5.0return 0;
}3.向正无穷取整 函数:ceil() 参数double 返回值:double #includemath.h
int main()
{printf(%f\n, ceil(5.4));//6.0return 0;
}4.四舍五入取整 函数:round() 参数:double 返回值:double #includemath.h
int main()
{printf(%f\n, round(5.4));//5.0return 0;
}2.取模与取余的区别和联系
在数学中余数的定义为 如果a和d是两个自然数d非零可以证明存在两个唯一的整数 q 和 r满足 a q*d r 且0 ≤ r d。其中q被称为商r 被称为余数。 注意:这里的余数r是大于等于0的。 在计算机中余数的定义 如果a和d是两个自然数d非零可以证明存在两个唯一的整数 q 和 r满足 a qd r其中q被称为商r 被称为余数。 注意:这里的余数是可以小于0的商的结果是向0取整的 比如:5/-2-2.5,向0取整为-2这里的 /准确的来说是取余 余数的求法:ra-qd5-(-2)*(-2)5-41,也就是用公式求。 C语言的 / 就是取余
在计算机中取模的定义 如果a和d是两个自然数d非零可以证明存在两个唯一的整数 q 和 r满足 a qd r其中q被称为商r 被称为余数。 说明:a/dq余r这里的/准确的来说是取模 注意:这里的余数是可以小于0的商的结果是向负无穷取整的 比如:5/-2-2.5,向负无穷取整为-3 余数的求法:用公式求,ra-qd5-(-3)*(-2)5-6-1. Python的 / 就是取模
3./两边异号的情况
1.左正右负 这里的ra-qda是被除数q是商d是除数 也就是a0,d0,q0,q * d 0,所以可以这样写r|a|-|q*d|, 1.当为取模时商实际上会比较小(负数)绝对值比较大所以|q*d||a|,因此r是小于0的 2.当为取余时商实际上会比较大(负数)绝对值比较小所以|qd||a|r是大于0的。 2.左负右正 这里的ra-qda是被除数q是商d是除数 也就是a0,d0,q0,q*d0,所以可以这样写r|q*d|-|a| 1.当为取模时商实际上会比较小(负数)绝对值比较大所以|q*d||a|,因此r是大于0的 2.当为取余时商实际上会比较大(负数)绝对值比较小所以|qd||a|r是小于0的。 九.运算符的优先级