【1】运算符
1.1逻辑运算符
&& || !
终端验证条件是否成立:
printf("%d\n",118>99); //1
printf("%d\n",18>99); //0
&& 逻辑与:全真为真,一假则假
|| 逻辑或:一真则真,全假为假
! 逻辑非:非真即假,非假即真
printf("%d\n",118>99 && 5>9 ); // 0
printf("%d\n",118>99 || 5>9 ); //1
printf("%d\n",!(118>99) || 5>9 ); //0
0为假 非0为真
printf("%d\n",5&&6); //1
printf("%d\n",(10/2)&&6); //1
printf("%d\n",(10/2==5)&&6); //1
截断法则:
逻辑与&&运算中,前边表达式结果为假,后边表达式不再执行,返回为假;
逻辑或||运算中,前边表达式结果为真,后边表达式不再执行,返回为真。
1.2 位运算符
二进制 0 1
& | ^ ~ << >>
& 按位与 :全 1 为 1,有 0 则 0
| 按位或 :有 1 则 1 ,全 0 为 0
^ 异 或 : 相同为 0 ,不同为 1
int a=6,b=10;
int c=a&b;
//6 : 110
//10:1010
//&: 10----2
printf("%d\n",c); //2
负数运算:(最左边表示符号位 0:正数 , 1:负数)
计算机中的整数 以 补码 的形式存储及计算
原码 | 反码 | 补码 | |
正数 | 相同 | 相同 | 相同 |
负数 | 相同 | 原码除符号位之外,其他位按位取反 | 反码+1 |
int a=-6,b=10; //a : 原码:1000 ... 0110 反码:1111 ... 1001 补码:1111 ... 1010
int c=a&b; // b : 0000 ... 1010
printf("%d\n",c); // c =10 0000 ... 1010 -->10
int4字节=32位
-6原码: 最左边表示符号位0正数1负数
1000 ... 0110
-6反码:
1111 ... 1001
-6补码:
1111...1010
10补码:
0000...1010
-6补码&10补码:
1111...1010
0000...1010
0000...1010补码
~ 取反:
1--->0 0--->1
int a=-6;
int c=~a;
printf("%d\n",c); //5
-6 原码: 最左边表示符号位 0正数 1负数
1000 ... 0110
-6反码: 1111 ... 1001
-6补码: 1111 ... 1010
~ : 0000 ... 0101===5
<< 左移:
左移几位,右边就补几个0
int a=6<<2; // 法1:6转成二进制,再左移
printf("%d\n",a); //24
法2:6*2^2=24
-6*2^2=-24
>> 右移:
右移几位,右边“丢弃”几位,左边补0
6>>2 //6转成二进制,再右移
6/2^2=1
注:-6/2^2== -2
************************************
置一公式:a | (1<<n)
置零公式:a & (~(1<<n))
11100001 第三位 1
00000100 1<<2
练习:a=3,b=5,对a和b的值进行交换。
int a=3,b=5;
int temp = 0;
temp = a;
a=b;
b=temp;
——————————————————————————————————————
a=a+b;
b=a-b;
a=a-b;
——————————————————————————————————————
a=a^b;
b=a^b;
a=a^b;
1.3 关系运算符
> >= < <= == !=
= 赋值
== 等于
eg : 0--18:x>0&&x<18
1.4 三目运算符(条件运算符 )
表达式1 ? 表达式2 :表达式3;
int a=3,b=5;
int max=a>b?a:b;
printf("%d\n",max); //5
1.5 赋值运算符
= += -= *= /= %=
a-=6------>a=a-6
赋值运算符 优先级最低
逗号运算符(顺序求值运算符)
a=(a*3,a+2,a-1);
()中有多个表达式时,运算结果为最后一个表达式的值
int a=3,b=5;
a=(a*3,a+2,a-1);
printf("%d\n",a); //2
优先级
单算移关与,异或逻条赋
单目运算符:++ -- ~ !
算术运算符:+ - * / %
移位运算符:<< >>
关系运算符:> >= < <= == !=
位与运算符:&
异或运算符:^
位或运算符:|
逻辑运算符:&& ||
条件运算符:? :
赋值运算符:=
分隔符
空格 tab 换行
标点符号
英文输入法输入
变量
程序运行过程中会发生变化的量
格式:
存储类型 数据类型 变量名
(auto) int a;
存储类型:决定变量存储位置
数据类型:决定开辟空间大小
变 量 名 :遵循标识符命名规则
名称 | (字节)大小 | 取值范围(了解) | |
int | 整型 | 4 | |
char | 字符型 | 1 | -2^7~2^7-1 |
short | 短整型 | 2 | |
long | 长整型 | 32位:4 ;64位:8 | |
float | 单精度浮点型 | 4 | 有效位数:6-7位 |
double | 双精度浮点型 | 8 | 15-16位 |
局部变量和全局变量的区别
局部变量 | 全局变量 | |
定义位置 | 函数体内部 | 函数体外部 |
初值 | 未初始化,值为随机值 | 未初始化,值为0 |
作用域 | 当前函数体内部 | 整个程序 |
声明周期 | 同当前函数共存亡 | 同整个函数体共存亡 |
存储位置 | 栈区 | 全局区 |
32: 2^32字节==4G
64:2^64 2^48(实际可用)
栈区:系统自动开辟、回收 (函数体内部定义的变量)
堆区:程序员手动开辟(malloc)、回收(free)
全局区、静态区:全局变量、static修饰的变量
常量区: char *p="hello"
常量
数值型常量
八进制、十进制、十六进制
浮点型常量
float double
字符常量
用 ' ' 包裹
char a='q';
char b='\n';
char c='n';
// \n 换行 n 字符 \ 转义字符
char a='A';
printf("%c\n",a); //A
char b='123';
printf("%c\n",b); //'3'
char c=0101; // \101 \后转义的为八进制
printf("%c\n",c); //A
char d='\101';
printf("%c\n",d); //A
char e='\x41'; // \x41 \x 后转义为十六进制
printf("%c\n",e); //A
\101 \后转义的为八进制
\x41 \x 后转义为十六进制
字符串常量
用“ ”包裹,'\0'字符结束标志
"hello"5个字符+'\0'字符串结束标志== 6个字符
标识常量
宏定义:
格式:#define + 宏名 + 常量值或表达式或函数
宏名:一般用大写命名,目的跟变量区分开
特点:先进行 单纯 的替换,替换完之后在进行计算
#define N 2
#define M N+3 // 2+3
#define NUM N+M/2+1 // 2+2+3/2+1
void main()
{
int a = NUM;
printf("%d\n",a); //a=6
}
宏定义实现求最大值
#include<stdio.h>
#define MAX a>b?a:b
int main(int argc, char const *argv[])
{
int a=6,b=9;
printf("%d\n",MAX);
return 0;
}
宏函数:
#include<stdio.h>
#define MAX(a,b) a>b?a:b
int main(int argc, char const *argv[])
{
printf("%d\n",MAX(6,3)); //6
return 0;
}
练习:写一个"标准"宏MIN,这个宏输入两个参数并返回较小的一个;
#include <stdio.h>
#define MIN(a,b) a<b?a:b
int main(int argc, char const *argv[])
{
printf("%d\n",MIN(8,9));
return 0;
}
局部变量可以和全局变量重名吗?
可以,遵循就近原则;在定义的函数体内部,以局部变量为主;其他位置以全局变量为主。