现阶段只需简单了解,后续会有详细介绍
算术操作符 |
---|
+ |
- |
* |
/ |
% |
这里主要介绍一下/和%的用法
#include <stdio.h>
int main()
{
printf("%d\n", 8 / 2);//4
printf("%d\n", 7 / 2);//3(7 / 2=3...1)
printf("%lf\n", 7.0 / 2);//3.5 /两端至少有一个数是小数时除出来才是小数
printf("%.2lf\n", 7.0 / 2);//3.50
return 0;
}
注: %f是打印float类型;%lf是打印double类型
#include <stdio.h>
int main()
{
printf("%d\n", 8 % 2);//0(8/2=4...0) % - 取模/取余
return 0;
}
移位操作符 | 名称 |
---|---|
>> | 右移位操作符 |
<< | 左移位操作符 |
int main()
{
int a = 1;//int类型是4个字节 = 32bit 00000000000000000000000000000001
a >> 1;//00000000000000000000000000000001整体向右移一个二进制位
a << 1;//00000000000000000000000000000001整体向左移一个二进制位
return 0;
}
位操作符(位:二进制位) | 名称 |
---|---|
& | 按位与 |
| | 按位或 |
^ | 按位异或 |
赋值操作符 |
---|
= |
+= |
-= |
*= |
/= |
&= |
|= |
^= |
>>= |
<<= |
int main()
{
int a = 0;
a = 10;
a = a + 5;
a += 5;//这两种写法是一个效果
a = a - 3;
a -= 3;//这两种写法是一个效果
a *= 3;
a /= 3;
return 0;
}
单目操作符 | 名称 |
---|---|
! | 逻辑反操作 |
- | 负值 |
+ | 正值 |
& | 取地址 |
sizeof | 操作数的类型长度(以字节为单位) |
~ | 对一个数的二进制按位取反 |
-- | 前置、后置-- |
++ | 前置、后置++ |
* | 间接访问操作符(解引用操作符) |
(类型) | 强制类型转换 |
注: (i) "+"是一个操作符,"2+3"中2为左操作数,3为右操作数,因此+是双目操作符,由此可知只有一个操作数的操作符就是单目操作符 (ii) C语言中0表示假,非0表示真(非0:1、5、-1……)
逻辑反操作、取地址:
//!叫做逻辑反操作,它只关注真假(把真变为假,把假变为真)
#include <stdio.h>
int main()
{
int a = 0;
scanf("%d", &a);//5 0 scanf函数中的&就是取地址
printf("%d\n", a);//5 0
printf("%d\n", !a);//0 1(假变为真时,语法规定输出的是1)
return 0;
}
用法举例:
负值、正值:
#include <stdio.h>
int main()
{
int a = -10;
int b = -a;
printf("%d\n", b);//10
int c = +a;
printf("%d\n", c);//-10
return 0;
}
sizeof:
//sizeof是操作符,不是函数,计算的结果单位是字节
#include <stdio.h>
int main()
{
int a = 10;
printf("%d\n", sizeof(a));//4
printf("%d\n", sizeof a );//4 这里不加()也可以,而函数必须加(),所以sizeof不是函数,是操作符!!!
printf("%d\n", sizeof(int));
printf("%d\n", sizeof int );//这样写是错误的
return 0;
}
数组中元素个数的计算就可以用到sizeof:
#include <stdio.h>
int main()
{
int arr[10] = { 0 };
printf("%d\n", sizeof(arr));//40,计算的是数组的总大小,单位是字节
printf("%d\n", sizeof(arr[0]));//4
printf("%d\n", sizeof(arr) / sizeof(arr[0]));//40 / 4 = 10
//因此数组中元素个数的计算如下
int sz = sizeof(arr) / sizeof(arr[0]);
return 0;
}
是否还记得strlen呢,它和sizeof又有什么区别呢:
#include <stdio.h>
#include <string.h>
int main()
{
char arr1[] = "abc";//a b c \0
char arr2[] = { 'a', 'b', 'c' };//a b c
printf("%d\n", strlen(arr1));//3
printf("%d\n", strlen(arr2));//随机值
printf("%d\n", sizeof(arr1));//4 sizeof只关注这个数据占据内存空间的大小,不关注内存中放的是什么
printf("%d\n", sizeof(arr2));//3
return 0;
}
总结: strlen是库函数,是求字符串长度的,关注的是字符串中是否有\0 ,统计\0之前出现的字符个数;sizeof是操作符,只关注占据了多大的内存空间,不关注内存中存放的数据,返回值的单位是字节
前置、后置++;前置、后置--:
#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 b = a++;//后置++,先使用,后++(b=a,a=a+1;)
printf("a=%d b=%d\n", a, b);//11 10
int b = --a;//(a=a-1,b=a;)
printf("a=%d b=%d\n", a, b);//9 9
int b = a--;(b=a,a=a-1;)
printf("a=%d b=%d\n", a, b);//9 10
return 0;
}
注: 以下是一个错位的代码,在不同的编译器上有不同的结果
#include <stdio.h>
int main()
{
int a = 1;
int b = (++a) + (++a) + (++a);
printf("b=%d\n", b);
return 0;
}
强制类型转换:
#include <stdio.h>
int main()
{
//int double
int a = (int)3.14;
printf("%d\n", a);//3
return 0;
}
关系操作符 | 名称 |
---|---|
> | 大于 |
>= | 大于等于 |
< | 小于 |
<= | 小于等于 |
!= | 用于测试“不相等” |
== | 用于测试“相等” |
逻辑操作符 | 名称 |
---|---|
&& | 逻辑与(并且,只关注真假) |
|| | 逻辑或(或者,只关注真假) |
逻辑与:
用法举例:
逻辑或:
用法举例:
注: if()后不用加“;”
条件操作符(三目操作符) |
---|
exp1 ? exp2 : exp3 |
#include <stdio.h>
int main()
{
int a = 3;
int b = 7;
int m = 0;
m = (a > b ? a : b);//如果a>b,那么a,否则b(以下写法效果和它相同)
//if (a > b)
// m = a;
//else
// m = b;
printf("m=%d\n", m);//m=7
return 0;
}
附:
exp1 | exp2 | exp3 |
---|---|---|
真 | √ | |
假 | √ |
逗号表达式 |
---|
exp1, exp2, exp3, …expN |
#include <stdio.h>
int main()
{
int a = 3;
int b = 0;
int c = 4;
int d = (a = b - 3, b = a + c, c = a - b, a = c + 3);
//a=-3 b=1 c=-4 a=-1
printf("%d\n", d);//-1
return 0;
}
注: 逗号表达式会从左到右依次计算,但是整个表达式的结果是最后一个表达式的结果。
下标引用 | 函数调用 | 结构成员 |
---|---|---|
[ ] | ( ) | . |
-> |
下标引用:
#include <stdio.h>
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
printf("%d\n", arr[7]);//8;[]就是下标引用操作符,arr,7是[]的两个操作数
//2 + 3;2,3是+的两个操作数
return 0;
}
函数调用:
int Add(int x, int y)
{
return x + y;
}
int main()
{
int a = 10;
int b = 20;
int c = Add(a, b);//()就是函数调用操作符
return 0;
}
结构成员: “.”、" ->"是结构体中使用的,后期介绍
C语言提供了丰富的关键字,这些关键字都是语言本身预先设定好的,用户自己是不能创造关键字的。
循环 | 分支 | 类型 | 自定义类型 | |
---|---|---|---|---|
break(停止) | switch | char | enum(枚举) | extern(声明外部符号的) |
continue(继续) | case | short | struct(结构体) | register(寄存器关键字) |
do while | break | int | union(联合体/共用体) | return(函数中返回) |
for | default(默认选项) | long | volatile(这个关键字后面再讲) | |
while | if…else… | long long | auto(自动变量) | |
goto | float | |||
double | ||||
const | ||||
sizeof | ||||
static | ||||
signed(有符号的) | ||||
unsigned(无符号的) | ||||
typedef(类型重定义) | ||||
void(无类型/空类型,用于函数返回值、参数这些地方) |
int main()
{
auto int a = 10;//所有的局部变量都是自动变量,所以auto一般就省略不写。局部变量a进入它的作用域自动创建,出它的作用域自动销毁
return 0;
}
int main()
{
unsigned int num = -10;//现阶段只要知道是怎么写的就可以了,具体输出后结果是什么以后会进行讲解
return 0;
}
typedef unsigned int unit;//给unsigned int重新取了一个名字叫做unit,unit = unsigned int
int main()
{
unsigned int num1 = 10;
unit num2 = 20;
return 0;
}
拓展:
//数据结构
typedef struct Node
{
int data;
struct Node* next;
}Node;
//这一段代码的意思为给
//struct Node
//{
// int data;
// struct Node* next;
//}
//重新取了一个名字叫做Node
//现在只要大致能看懂就行,后期会深入讲解
int main()
{
register int num = 10;//register 起一个建议的作用,并不是写了register就一定会放到寄存器里,还是取决于编译器的,编译器如果发现这一变量被频繁大量使用,那么这个变量的值就可能被放到寄存器中,如果编译器觉得没必要把它放到寄存器中,那它就不会被放进去。即使不写register,现在的编译器只要觉得有必要把它放到寄存器中,编译器就会把它放到寄存器中
return 0;
}
附:
在C语言中,static是用来修饰变量和函数的,其分为以下三种:
修饰局部变量: 首先看一下不加static,代码运行之后的结果:
代码具体是如何运行的呢? 无static修饰局部变量代码运行过程
再来看一下加上static,代码运行之后的结果:
代码具体是如何运行的呢? static修饰局部变量代码运行过程
总结: static修饰局部变量的时候改变了变量的存储类型,普通的局部变量是存储在栈区的,被static修饰的变量是存储在静态区的,存储在静态区的变量,出了作用域不会销毁,依然存在,所以静态变量的生命周期就是程序的生命周期,程序结束的时候,静态变量才回收空间。(静态变量的生命周期变长了,作用域不变)
附:
修饰全局变量: 首先看一下不加static,代码运行之后的结果:
再来看一下加上static,代码运行之后的结果:
由图可知,这个代码是错误的,g_val是无法输出的
修饰函数: 首先看一下不加static,代码运行之后的结果:
注: int Add(int x, int y)后面不要加“;”
再来看一下加上static,代码运行之后的结果:
由图可知,这个代码是错误的,sum是无法输出的
其余关键字会在后期碰到时进行讲解!