大家好,这里是anduin,这次的主题依旧是初识C语言,和上次不同,这次我们主要讲两大块,对于一些知识,我们选择略讲,但是对于一些我觉得重要的知识我会对其进行精讲并做一些补充,其余的知识我会逐渐在以后一一讲解。话不多说,接下来就开始初识C语言吧!(以下程序均在vs2022中编译)
目录
10. 操作符
算数操作符
/ 操作符
为了让我们的讲解更加具有针对性,我们分正数和负数两部分进行讲解:
/ 操作符对正数
#include<stdio.h>
int main()
{
int a = 7 / 2;
printf("%d\n", a);//3
}
#include<stdio.h>
int main()
{
float f = 7 / 2;
printf("%f\n",f);//3.000000
}
/ 操作符对负数
#include<stdio.h>
int main()
{
int i = -2.9;
int j = 2.9;
printf("%d\n",j);//-2
printf("%d\n",j);//2
return 0;
}
小科普
trunc - 取整函数
#include<math.h>
int main()
{
printf("%d\n",(int)trunc(-2.9));//-2
printf("%d\n",(int)trunc(2.9));//2
}
floor - 地板取整
#include<stdio.h>
#include<math.h>
int main()
{
printf("%.lf\n",floor(-2.9));//-3
printf("%.lf\n",floor(-2.1));//-3
printf("%.lf\n",floor(2.9));//2
printf("%.lf\n",floor(2.1));//2
}
ceil - +∞取整
#include<stdio.h>
int main()
{
printf("%.lf\n",ceil(-2.9));//-2
printf("%.lf\n",ceil(-2.1));//-2
printf("%.lf\n",ceil(2.9));//3
printf("%.lf\n",ceil(2.1));//3
}
round - 四舍五入取整
是的你没有看错,与我们平常思维方式相同的四舍五入取整来了,上代码:
#include<math.h>
int main()
{
printf("%.lf\n",round(-2.9));//-3
printf("%.lf\n",round(-2.1));//-2
printf("%.lf\n",round(2.9));//3
printf("%.lf\n",round(2.1));//2
}
% 操作符
对于此部分我们依旧是从正数和负数两方面进行剖析:
% 操作符对正数
#include<stdio.h>
int main()
{
int a = 10;
int d = 3;
printf("%d\n",a%d);//1
//因为:a=10,d=3,q=3,r=1 0<=r<d(3)
//所以:a=q*d+3 -> 10=3*3+1
return 0;
}
-
% 操作符对负数
int main()
{
int a = - 10;
int d= 3;
printf("%d\n",a%d);//-1
}
很显然,结果不满足定义中的0<=r<d,故后来就有了一个修订版的定义:
根据定义,这里的结果也能解释了,即-10 = (-3)*3+(-1)。
移位操作符
位操作符
赋值操作符
由于赋值操作符便于理解,我们挑两个讲一下(详情见注释):
int main()
{
int a = 10;//创建变量,并初始化
a = 20;//赋值
a = a+5//等价于 a+=5
a = a-5//等价于 a-=5
}
单目操作符
我们常见的操作符比如+都有两个操作数,表示为左操作数+右操作数,这种操作符叫做双目操作符。
单目操作符其实就是只有一个操作数的。
在这里,对于!,-,+等操作符都便于理解,而对于&和*我打算之后在指针部分讲解,这里我们着重讲一下--,和++操作符(详情见注释):
#include<stdio.h>
int main()
{
int a = 10;
int b = ++a;//前置++,先++后使用
//a=a+1,b=a
printf("a=%d b=%d\n",a,b);//11 11
---------------------------------
int a = 10;
int b = a++;//后置++,先使用,后++
//b=a,a=a+1
printf("a=%d b=%d\n",a,b);//11 10
---------------------------------
int a = 10;
int b = --a;//前置--,先--后使用
//a=a-1,b=a
printf("a=%d b=%d\n",a,b);//9 9
---------------------------------
int a = 10;
int b = a--;//后置--,先使用,后--
//b=a,a=a-1
printf("a=%d b=%d\n",a,b);//10 9
}
关系操作符
前几个操作符,也就是对应的大于,大于等于,小于,小于等于等比较关系的操作符,这里我们讲一下后两个操作符。
例1
int main()
{
int a = 3;
int b = 3;
if(a!=b)
{
printf("hehe\n");
}
if(a==b)
{
printf("haha\n");
}
//结果为hehe
}
运行结果如下:
例2
#include<stdio.h>
int main()
{
char arr1[] = "abcdef";
char arr2[] = "abcdef";
if(arr1==arr2)
{
printf("==\n");
}
else
{
printf("!=\n");
}
}
#include<stdio.h>
#include<string.h>
int main()
{
char arr1[] = "abcdef";
char arr2[] = "abcdef";
if(strcmp(arr1,arr2)==0)
{
printf("==\n");
}
else
{
printf("!=\n");
}
}
再次运行:
逻辑操作符
int main()
{
int a= 3;
int b = 0;
int c = a && b;
printf("%d\n",c);//真为1,假为0
if(a&&b)
{
printf("hehe\n");
}
if(a||b)
{
printf("haha\n);
}
}
运行得:
条件操作符
#include<stdio.h>
int main()
{
int a = 10;
int b = 0;
b = (a>5?3:-3);
printf("%d\n",b);//3
return 0;
}
#include<stdio.h>
int main()
{
int a = 10;
int b = 0;
if(a>5)
{
b=3;
}
else
{
b=-3;
}
printf("%d\n", b);
}
逗号表达式
#include<stdio.h>
int main()
{
int a=3;
int b=5;
int c=0;
int d= (a+=2,b=b-c+a,c=a+b);
// a=5 b=10 c=5+10
printf("%d\n",d);
}
下标引用、函数调用和结构成员
对于这类操作符我们讲解一下[ ]操作符:
#include<stdio.h>
int main()
{
int arr[10] = {0};
arr[4]=5;
return 0;
}
11. 常见关键字
数据类型关键字(12个)
- char:声明字符型变量或函数
- short:声明短整型或函数
- Int :声明整型变量或函数
- long :声明长整型变量或函数
- signed:声明有符号类型变量或函数
- unsigned:声明无符号整形变量或函数
- foat:声明浮点型变量或函数
- double:声明双精度变量或函数
- struct:声明结构体变量或函数
- union:声明共用体(联合)数据类型
- enum:声明枚举类型
- void:声明函数无返回值或无参数,声明无类型指针
控制语句关键字(12个)
1.循环控制(5个)
- for:一种循环语句
- do:循环语句的循环体
- while :循环语句的循环条件
- break:跳出当前循环
- continue:结束当前循环,开始下一轮循环
2.条件语句(3个)
- if:条件语句
- else:条件语句否定分支
- goto:无条件跳转语句
3.开关语句(3个)
- switch:用于开关语句
- case:开关语句分支
- default:开关语句中的"其他"分支
4.返回语句(1个)
- return:函数返回语句(可以带参数,也可以不带参数)
5.存储类型关键字(5个)
- auto:声明自动变量,一般不使用
- extern:声明变量实在其他文件中声明
- register:声明寄存器变量
- static:声明静态变量
- typedef:用以给数据类型取别名(但是该关键字被分到存储关键字分类中,虽然看起来没什么相关性)
注意:存储关键字,不可以同时出现,也就是说,在一个变量定义的时候,只能有一个。
6.其它关键字(3个)
- const:声明只读变量
- sizeof:计算数据类型长度
- volatile:说明变量在程序执行中可被隐含地改变
auto
int main()
{
auto int a = 10;//局部变量都是auto类型的,因此auto基本会被省略
return 0;
}
typedef
本质
使用方法
#include<stdio.h>
typedef unsignde int u_int;
int main()
{
u_int x = 0;
return 0;
}
作用
register
存储金字塔
寄存器存在的本质
register 修饰变量
#include<stdio.h>
int main()
{
register int a = 10;
return 0;
}
register 修饰什么变量
- 局部变量(全局变量由于其特性会导致CPU寄存器被长时间占用)
- 不会被写入的(写入就需要写回内存,register本身就是快速读取,后续还要读取检测的话,就与原目的背道而驰了)
- 高频被读取的变量(俗话说把钱用在刀刃上,存入了寄存器,当然要经常使用的)
- 如果要使用,不要大量使用,寄存器的数量是有限的!
小科普
#include<stdio.h>
int main()
{
register int a = 0;
printf("&a = %p\n", &a);
return 0;
}
编译运行: