一、操作符
1.算术操作符
+ - *
/ : 取商
% : 取余
若a < b,则a % b = a
若a % b = c,则0 <= c <= b-1
若两个整型数相除 /,结果有小数时,小数部分的结果会被舍弃。
保留小数:强制类型转换 *1.0
例:int a = 6;
int b = 5;
printf("%lf\n", a*1.0 / b);
2.移位操作符
C语言的位操作符,操作的都是数字的二进制补码位。
>>右移
根据数据类型,二进制补码整体移动,末尾补0。
<<左移
例:int a = 1;
int b = a<<1;
则a = 1, b = 2
3.位操作符
& 按位与 | 按位或 ^ 按位异或
例:int a = 3; //011
int b = 5; //101
int c = a & b; //001
则c = 1
4.赋值操作符
== += -= *= /= &= ^= |= >>= <<=
赋值: =
判断相等:==
例:a += 10; //a = a+10;
5.单目操作符
(1)逻辑反操作 !
C语言中,用0表示假,一切的非0表示真。
例:int a = 10; int a = 0;
则!a = 0 则!a = 1
(2)sizeof
计算变量 / 类型所占内存大小,以字节为单位。
(3)按位取反 ~
数字在内存中都是以二进制补码的形式存储的,最高位为符号位。
正数的符号位为0,负数的符号位为1。
原码 ——> 反码 ——> 补码
符号位不变, 反码+1
其余取反。
正数的原码 = 反码 = 补码
负数要变换
例:int a = 0;
int b = ~a;
则b = -1
a:0.......0 32个0
~a:1.....1 32个1(b的补码)-> 11111111.....0(b的反码)-> 100000....1(b的原码)
printf打印的是数字的原码
(4)前置和后置
例:前置 ++(先++,后使用) 后置++(先使用,后++)
int a = 10; int a = 10;
int b = ++a; int b = a++;
则a = 11,b = 11 则a = 11,b = 10
(5)强制类型转换
例:int a = (int) 3.14;
则a = 3
直接截取整数部分
6.关系操作符
> >= < <= != ==
7.逻辑操作符
&& 逻辑与 || 逻辑或
例:int a = 3;
int b = 5;
int c = a && b;
则c = 1
8.条件操作符
三目操作符
exp1 ? exp2 : exp3;
例:max = (a > b ? a : b);
9.逗号表达式
exp1 , exp2 , exp3 , .... , expN
逗号表达式最终值为最右边的值,并且逗号表达式的优先级最低。
例:int a = (5,6); a = (a = 3*5, a*4, a = a+5);
则a = 6 则a = 15+5 = 20
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
//逗号表达式
int main()
{
int x = 1;
int y = 1;
int z = 0;
z = (x++, y++, ++y);
printf("第一个逗号表达式结果为:\n");
printf("%d %d %d\n", x, y, z); //2 3 3
x = 1;
y = 1;
z = (x++, y++, y++);
printf("第二个逗号表达式结果为:\n");
printf("%d %d %d\n", x, y, z); //2 3 2
x = 1;
y = 1;
z = x++, y++, ++y;
printf("第三个逗号表达式结果为:\n");
printf("%d %d %d\n", x, y, z); //2 3 1
return 0;
}
10.漏掉的操作符
下标引用:[ ]
函数调用:()
结构体成员:. ->
取地址符号:&
指针:*
二、常见关键字
1.寄存器变量 register
例:register int a = 10; //访问快
2.有符号数 signed
int 定义的变量是有符号的,int = signed int
无符号数:unsigned int
3.类型重定义 typedef
例:typedef unsigned int u_int;
unsigned int num = 20;
相当于
u_int num = 20;
4.static
全局变量 -> 静态的全局变量
变量
局部变量 -> 静态的局部变量
static修饰
函数
(1)局部变量
例:static int a = 1;
使局部变量的生命周期变长,可以保存上一次的值。
(2)全局变量和函数
static修饰全局变量,使得extern失去作用效果。改变其作用域,使其只能在自己的所在源文件内部使用。
static修饰函数,使得extern失去作用效果。改变其链接属性,由外部的链接属性变为内部的链接属性,使其只能在自己的所在源文件内部使用。
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
//static修饰局部变量
void test ()
{
static int a = 1;
a++;
printf("a=%d\n", a);
}
int main ()
{
int i = 0;
while(i < 5)
{
test();
i++;
}
return 0;
}
5.#define定义常量和宏
(1)#define定义标识符常量
例:#define MAX 100
(2)#define定义宏
例:#define MAX(x,y)(x>y?x:y)(无参数类型) 宏模块之间不能有空格
调用:
max = MAX(a,b)
定义了一个MAX(x,y)的宏
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
//#define定义宏
#define MAX(x,y)(x>y?x:y)
int main ()
{
int a = 0;
int b = 0;
int c = 0;
printf("a=");
scanf("%d", &a);
printf("b=");
scanf("%d", &b);
c = MAX(a,b);
printf("最大值是:%d\n", c);
return 0;
}
三、指针
1.地址的产生
用地址访问内存,那么地址是如何产生的呢?
32位计算机,有32根地址线 (正/负),能产生
个地址,0~
。
每个地址用32bit = 4byte来表示,由计算机设计原理得知,1个地址(内存单元)的大小是1个byte。
所以32位系统最多只能支持4GB内存条
内存单元就是房间 地址(指针)就是房间号
内存的大小就是房间的大小,地址的大小就是房间号的大小;
地址的数量,就是房间的数量,也就是内存单元的数量。
2.指针变量
指针变量是用来存放地址的
例:int a = 10;
int* p = &a;
int*是p的数据类型
p是指针变量
p里面存放的是a的地址,%p以地址类型打印。
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
//指针变量
int main ()
{
int a = 10;
int* p = &a;
printf("a的地址是:%p\n", p);
printf("a=%d\n", *p);
*p = 20;
printf("a=%d\n", *p);
return 0;
}
3.解引用*
*p = 20;(通过对a的地址解引用来修改a的值)
地址:p &a
内容:*p a
4.指针变量的大小
指针(地址)大小,在32位平台是4byte,32bit;在64位平台是8byte,64bit。
例:a为int型,占4个字节,占4个内存单元,所以占4个地址,但计算机只读首地址,4个地址是连续的,而且地址是动态变化的。
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
//指针变量的大小
int main ()
{
printf("%d\n", sizeof(char*));
printf("%d\n", sizeof(short*));
printf("%d\n", sizeof(int*));
printf("%d\n", sizeof(double*));
return 0;
}