目录
一、枚举
1.枚举
"枚举" 是指将变量的值一一列举出来,变量的值只限于列举出来的值的范围内。
作用:
1.为了提高代码可读性
2.提高代码的安全性
2.语法
枚举类型:
enum 枚举名
{
列举各种值 //枚举元素//枚举常量
};
注意:
列举各种值,之间用逗号隔开,不需要写类型名
eg:
enum fire
{
LITTLE_FIRE,
MIDDILE_FIRE,
LARGE_FIRE,
}; //表示 定义了一种 枚举类型
注意:
(1). 枚举中逐个列举的值,默认是从0开始
如果有给定的值,则后续没有给值的 枚举元素 依次 加1
(2). 枚举类型的 本质 实际是一个int类型的数据
(3). 枚举类型的变量 与 整型类型的变量通用的
(4). 与 宏定义对比
区别:
使用阶段不同 --- 宏定义 --- 预处理阶段
枚举 --- 编译阶段 要检查语法
运行阶段 参与代码运行
可读性
都提高了可读性
枚举,更能说明有相关性的一些值间关系
从键盘输入 1~7打印对应的星期英文
#include <stdio.h>
enum week
{
MON = 1,
TUE,
WED,
THU,
FIR,
SAT,
SUN,
};
int main(void)
{
int n=0;
scanf("%d",&n);
switch(n)
{
case MON:
printf("Monday\n");
break;
case TUE:
printf("Tuesday\n");
break;
case WED:
printf("Wednesday\n");
break;
case THU:
printf("Thursday\n");
break;
case FIR:
printf("Firday\n");
break;
case SAT:
printf("Saturday\n");
break;
case SUN:
printf("Sunday\n");
break;
}
return 0;
}
3.typedef
typedef //type define
//本意 不是定义类型
//给类型起别名(是已有的类型)
struct student
{
};//结构体类型
typedef struct student stu_t;
//此时stu_t相当于struct student这个结构体类型的别名,可以用它来定义变量
stu_t s1;
二、位运算
位运算: 可以直接操作二进制位
注意:浮点数不能做位运算
1.与运算
& 与运算(之前的&&与运算是逻辑运算,这个&与运算是位运算)
运算规则:一假则假
eg:
1010 1010 // 0xaa
0011 0011 & // 0x33
-----------------
0010 0010 //0x22
应用:清零
最高位清零
#include <stdio.h>
int main(int argc, const char *argv[])
{
unsigned char ch1=0xff;
//printf("ch1 & 0x7f = %#x\n", ch1&0x7f);
printf("ch1 = %#x\n",ch1&~(1<<7));//清零
return 0;
}
通过左移可以避免想一个数来进行&运算
2.或运算
| 或运算
运算规则:一真则真
eg:
1010 1010 // 0xaa
0011 0011 | // 0x33
------------------
1011 1011 //0xbb
应用:置1
最高位置1
#include <stdio.h>
int main(int argc, const char *argv[])
{
unsigned char ch2=0x00;
//printf("ch2 | 0x80 = %#x\n",ch2 |0x80);
printf("ch2 = %#x\n",ch2 | 1<<7);//置1
return 0;
}
3.取反
~ 取反
运算规则:真假相对
eg:
~0xaa
1010 1010 // 0xaa
0101 0101 //0x55
4.异或
^ 异或
运算规则:相同为 0,不同为 1
eg:
1010 1010 // 0xaa
0011 0011 ^ // 0x33
----------------
1001 1001 //0x99
应用:加密,交换
使用中间量交换两个数:
int temp;
temp = a;
a = b;
b = temp;
不使用中间量交换两个数
a = a + b; //
b = a - b; //b = a(原来的a)
a = a - b; //
a = a ^ b;
b = a ^ b;
a = a ^ b;
5.<< 左移
写法:
a<<n //表示将 a这个数据 左移 n位
左移1位 相当于乘 2
0000 0001 //1
0000 0010 //2
注:
最低位 补0
6.>> 右移
写法:
a>>n //表示将 a这个数据 右移 n位
右移1位 相当于除 2
算术右移
//看符号位 看数据类型
如果是有符号类型的数据,右移时,最高位补的是符号位
如果是无符号类型的数据,右移时,最高位补的0
#include <stdio.h>
int main(int argc, const char *argv[])
{
int b=0xffffffff;
int i=0;
for(i=0;i<16;++i)
{
b=b&~(1<<(2*i));//偶数位清零
}
printf("b=%#x\n",b);
return 0;
}
#include <stdio.h>
int main(int argc, const char *argv[])
{
int m=0x00;
int i=0;
for(i=1;i<17;++i)
{
m=m | (1<<(2*i-1));//奇数位置1
}
printf("m=%#x\n",m);
return 0;
}
统计int类型数据中1的个数
#include <stdio.h>
int main(int argc, const char *argv[])
{
int n=121314;
printf("n=%#x\n",n);
int i=0;
int flag=0;
for(i=0;i<32;++i)
{
if(n & (1<<i))//非0即为真
{
flag++;
}
}
printf("flag = %d\n",flag);
return 0;
}
实现一个循环左移,将移出去的数补到最后。
思路:判断最高位是否为1,如果为1,左移之后在最低位置1;如果为0,直接左移即可,因为最低位本身就补0。
#include <stdio.h>
int main(void)
{
int n=0xf0000001;
printf("before n=%#x\n",n);
int i=0;
for(i=0;i<1;++i)
{
if((n&0x80000000)!=0)
{
n=n<<1;
n=n|1;
}
else
{
n=n<<1;
}
}
printf("after n=%#x\n",n);
return 0;
}
三、指针函数
1.指针函数
指针函数:返回值为指针类型的函数
eg:char *strcpy(char *dest,const char *src);
函数指针:指向函数类型的指针 //基类型为函数类型的指针
2.堆
堆的特点是手动申请,手动释放。
堆上的空间用malloc开辟:
void *malloc(size_t size);
参数:
size //表示申请的空间的大小,单位字节
返回值:
成功 返回 申请到内存空间的地址
失败 返回 NULL
//释放函数
void free(void *ptr);
释放之前申请的堆上的空间
参数:
ptr 一定是之前申请到堆上空间的地址
free释放后的空间
1.一般不再使用
2.指向这块空间的指针变成野指针
3.free之后对应空间上的内容也不要使用
注意:
1. malloc和free成对出现
2. free只是释放了空间 --- 表示这块空间 又自由了
但是 这块空间上的数据 并不会清零
3. 不要多次free
定义整型一维数组 5个元素,数组放在堆上,给5个值,打印输出
#include <stdio.h>
#include <stdlib.h>//使用malloc注意加上此头文件
int main(int argc, const char *argv[])
{
int *p=malloc(20);
int i=0;
for(i=0;i<5;++i)
{
*(p+i)=i+1;
}
for(i=0;i<5;++i)
{
printf("%d ",*(p+i));
}
putchar('\n');
free(p);
return 0;
}