笔记
1.逻辑运算符
&& || !
&&逻辑与:全真为真
||逻辑或:一真为真
!逻辑非:真为假,假为真
输出1为真,0为假
&&逻辑与
#include <stdio.h>
int main()
{
printf("%d\n",3>2&&3>1);
}
//输出为1
#include <stdio.h>
int main()
{
printf("%d\n",3<2&&3>1);
}
//输出为0
||逻辑非
#include <stdio.h>
int main()
{
printf("%d\n",3<2||3>1);
}
//输出为1
#include <stdio.h>
int main()
{
printf("%d\n",3<2||3<1);
}
//输出为0
!逻辑非
#include <stdio.h>
int main()
{
printf("%d\n",3<2||!(3<1));
}
//输出为1
#include <stdio.h>
int main()
{
printf("%d\n",!(3<2)&&!(3<1));
}
//输出为1
注:0为假,非零为真
#include <stdio.h>
int main()
{
printf("%d\n",10&&88);
}
//输出为1
截断法则:逻辑与中,表达式前面出现假,则后面不运行
逻辑或中,表达式前面出现真,则后面不运行
#include <stdio.h>
int main()
{
int a=1,b=2,c=3,d=4,m=2,n=2;
(m=a>b)&&(n=c>d);
printf("%d %d",m,n);
}
//输出0 2
#include <stdio.h>
int main()
{
int a=1,b=2,c=3,d=4,m=2,n=2;
(m=a<b)||(n=c>d);
printf("%d %d",m,n);
}
//输出1 2
2.位运算符
& | ~ ^ << >>
&:按位与 全1出1,有0出0
|:按位或 有1出1,全0出0
~:取反 1为0,0为1
^:异或 相同为0,相异为1
<<:左移 二进制左移,低位变0
>>:右移 二进制右移,高位变0
&
#include<stdio.h>
int main()
{
int a = 6,b = 7; //a:0110 b:0111
printf("%d\n",a&b);//a&b 0110==6
}
|
#include<stdio.h>
int main()
{
int a = 6,b = 7; //a:0110 b:0111
printf("%d\n",a|b);//a|b 0111==7
}
~
#include<stdio.h>
int main()
{
int a = 6,b = 7; //a:0110 b:0111
printf("%d\n",~(a)&b);//~a:1001 ~(a)&b==1
}
^
#include<stdio.h>
int main()
{
int a = 6,b = 7; //a:0110 b:0111
printf("%d\n",a^b);//a^b==0001==1
}
<<
#include<stdio.h>
int main()
{
int a = 6,b = 7; //a:0110 b:0111
printf("%d\n",a<<2);//a<<2 == 01 1000 ==24
}
计算公式:a*2^n n为移的位数
置一公式:a|(1<<n)
置零公式:a&(~(1<<n))
>>
#include<stdio.h>
int main()
{
int a = 6,b = 7; //a:0110 b:0111
printf("%d\n",a>>2);//a<<2 == 0001 ==1
}
两个变量值交换
1.
#include<stdio.h>
int main()
{
int a = 6,b = 7,t;
t = a,a = b,b = t;
printf("%d,%d",a,b); //7 6
}
2.
#include<stdio.h>
int main()
{
int a = 6,b = 7;
b = a^b;
a = a^b;
b = a^b;
printf("%d,%d",a,b);//7 6
}
因为a^a = 0,b^b = 0,所以a^a^b = b,b^b^a = a.
先执行b = a^b,第二句a = a^b就为a = a^a^b = b.
最后执行b = a^b 就是b = b^b^a = a.
二进制补码
原码-->反码-->补码
原码 | 反码 | 补码 | |
正数 | 不变 | 不变 | 不变 |
负数 | 不变 | 除符号位其余相反 | 反码+1 |
符号位为最高位,1为负数,0为正数
如int a=10 int占4个字节,也就是32位
所以10原码:0000 0000 0000 0000 0000 0000 0000 1010
反码:0000 0000 0000 0000 0000 0000 0000 1010
补码:0000 0000 0000 0000 0000 0000 0000 1010
如int a=-10
原码:1000 0000 0000 0000 0000 0000 0000 1010
反码:1111 1111 1111 1111 1111 1111 1111 0101
补码:1111 1111 1111 1111 1111 1111 1111 0110
#include<stdio.h>
int main()
{
int a = -6,b = 7;
printf("%d\n",a&b);//2
}
-6
原码:1000 0000 0000 0000 0000 0000 0000 0110
反码:1111 1111 1111 1111 1111 1111 1111 1001
补码:1111 1111 1111 1111 1111 1111 1111 1010
7
补码:0000 0000 0000 0000 0000 0000 0000 0111
-6&7=0000 0000 0000 0000 0000 0000 0000 0010=2
因为最高位是0,所以是正数,补码和原码一致
#include<stdio.h>
int main()
{
int a = -6,b = -7;
printf("%d\n",a&b);//-8
}
-7
原码:1000 0000 0000 0000 0000 0000 0000 0111
反码:1111 1111 1111 1111 1111 1111 1111 1000
补码:1111 1111 1111 1111 1111 1111 1111 1001
-6&-7=1111 1111 1111 1111 1111 1111 1111 1000
这一步算的是补码,因为最高位是1,所以是负数,和原码不一致
反码:1111 1111 1111 1111 1111 1111 1111 0111
原码:1000 0000 0000 0000 0000 0000 0000 1000 =-8
#include<stdio.h>
int main()
{
int a = 6;
printf("%d\n",~a);//-7
}
6补码:0000 0000 0000 0000 0000 0000 0000 0110
~6补码:1111 1111 1111 1111 1111 1111 1111 1001
反码:1111 1111 1111 1111 1111 1111 1111 1000
原码:1000 0000 0000 0000 0000 0000 0000 0111 = -8
3.关系运算符
> < >= <= != ==
注:==和=不一样,=是赋值,==是相等
0~9用关系运算符表示:a>=0&&a<=9
4.三目运算符
表达式1?表达式2:表达式3;
#include<stdio.h>
int main()
{
int a = 6,b=7,c;
printf("%d\n",c=a>b?a:b);//7
}
如果满足表达式1则执行表达式2,否则执行表达式3
5.赋值运算符
= += -= %= *= /=
= a=b
#include<stdio.h>
int main()
{
int a = 6,b=7;
printf("%d\n",a=b);//7
}
+= a=a+2
#include<stdio.h>
int main()
{
int a = 6,b=7;
printf("%d\n",a+=2);//8
}
-= a=a-2
#include<stdio.h>
int main()
{
int a = 6,b=7;
printf("%d\n",a-=2);//4
}
%= a=a%2
#include<stdio.h>
int main()
{
int a = 6,b=7;
printf("%d\n",a%=2);//0
}
*= a=a*2
#include<stdio.h>
int main()
{
int a = 6,b=7;
printf("%d\n",a*=2);//12
}
/= a=a/2
#include<stdio.h>
int main()
{
int a = 6,b=7;
printf("%d\n",a/=2);//3
}
6.运算符优先级
单目运算符: ~ ++ -- !
算术运算符: * / %,+ -
移位运算符: << >>
关系运算符: > >= < <= == !=
位与运算符: &
异或运算符: ^
位或运算符: |
逻辑运算符: &&大于||
条件运算符: ? :
赋值运算符: = += -= *= /= %=
7.标点符号
, ; [ ] {} () 英文标点
8.分隔符
空格 tab \n
变量
程序运行的过程中会变化
变量的格式:存储类型 数据类型 变量名
如:auto(可省略) int a;
存储类型:决定变量存储位置
数据类型:决定变量开辟空间大小
变量名:遵循标识符命名规则
数据类型:
名称 | 字节大小 | 取值范围 | |
int | 整型 | 4 |
-2^31~2^31-1 |
char | 字符型 | 1 |
-2^7~2^7-1 |
short | 短整型 | 2 |
-2^15~2^15-1 |
long | 长整型 | 8 |
-2^63~2^63-1 |
float | 单精度浮点型 | 4 |
有效位数6-7位 |
double | 双精度浮点型 | 8 |
有效位数15-16位
|
可用sizeof()函数查看字节数,如printf("%ld\n",sizeof(int));
局部变量和全局变量的区别
局部变量 | 全局变量 | |
定义位置 | 函数体内部 | 函数体外部 |
初始值 | 未初始化为随机值 | 未初始化为0 |
存储位置 | 栈区 | 全局区 |
生命周期 | 同当前函数体共存 | 同整个程序共存 |
作用域 | 当前函数体内部 | 整个程序 |
常量
程序运行过程中不会发生变化
整型常量
八进制 十进制 十六进制
字符常量
字符:由' '包裹的单个字符
字符串:由" "包裹的多个字符,'\0'为字符串结束的标志
浮点型常量
float double
标识常量
宏定义:
格式为 #define 宏名 常量值或表达式或代码段
宏名一般用大写表示
注意:先原样替换再计算
#include<stdio.h>
#define N 2
#define M N+2
#define NUM 2+M*3+1
int main()
{
printf("%d\n",NUM); //11 NUM=2+2+2*3+1
}
#include<stdio.h>
#define MAX a>b?a:b
int main()
{
int a=3,b=4;
printf("%d\n",MAX); //4
}
#include<stdio.h>
#define MAX(a,b) a>b?a:b
int main()
{
printf("%d\n",MAX(3,4)); //4
}
作业
1.
程序运行的结果是___
#include<stdio.h>
#define SQR(X) X*X
void main()
{
int a=10,k=2,m=1;
a/=SQR(k+m)/SQR(k+m);
printf("%d\n",a);
}
//a/= 2+1*2+1/2+1*2+1
//a=10/7=1
2.
以下程序输出结果是____
#include<stdio.h>
#define M 5
#define N M+M
void main()
{
int k;
k=N*N*5;
printf("%d\n",k);
}
//M+M*M+M*5=5+5*5+5*5=55