1.函数
函数:数学中就学习过函数如: f(x)=ax+b
C语言中函数的作用与数学中差不多,可以理解为一个模块的代码,完成一个独立的功能
程序执行先执行main主函数,当主函数调用其他函数时,再执行被调用的函数,执行完毕再返回主函数
函数的作用可以简化代码,代码复用
函数可以多次被调用
//x,y是形式参数,简称形参 int Add(int x, int y)//Add是函数名称,int是返回值类型,x,y接受传入的a,b { int z = x + y; //该函数要返回两数相加的和,所以返回z return z;//函数返回z,z是整形,所以Add函数的返回值类型为int } int main() { int a = 0; int b = 0; //输入 scanf("%d %d", &a, &b); //1.直接相加方式 //int sum = a + b;//完成函数相加,求的只是a和b相加的值。 //2.调用函数方式 //Add函数的作用是计算传入两个值的和。只要想算两个数的和都可以调用Add函数。 //这里传入的是a,b是实际参数,简称实参。 int sum = Add(a, b);//函数要有返回值,这里Add函数返回的值放到sum中 printf("%d", sum); return 0;//main函数执行完返回0。整形 }
2.数组
数组,可以保存一组相同类型的数据。一组相同类型数据的集合。
//数组,可以保存一组相同类型的数。一组相同类型的集合。 #include<stdio.h> int main() { //数组的定义 //存放10个数,数组内容称为元素。这样就不用创建10个变量来存储这10个元素。 int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };//整型数组。arr是数组名。 char ch[8];//字符数组,ch是数组名,可以存放8个字符。 //数组的下标 //为了更方便的找到数组中的每个元素。每个元素都有自己的下标。 //语法规定下标从0开始往后排 //arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; //下标 0 1 2 3 4 5 6 7 8 9 //访问元素6 6的下标是5 printf("%d\n", arr[5]);//输出5 //输出整个数组 int i = 0;//i为下标 while (i < 10)//循环输出 { printf("%d ", arr[i]);//从下标0开始输出 i++;//每输出一个元素,下标加一,就是i=i+1; } return 0; }
3.操作符
因为C语言有很多操作符,所以就很灵活,有些操作符甚至可以操作到二进制位。
a+b,a和b是加号的操作数,有两个操作数的操作符是双目操作符。有一个操作数的单目操作符如-负号。
3.1算术操作符
+ | 加 |
- | 减 |
* | 乘 |
/ | 除:计算结果是整除以后的得到的商 除法有 整数除法 和 浮点型数据 |
% | 取模(取余):计算两个数相除以后的余数 只适用于整数运算 |
在VS编译器中写的小数,如1.2,编译器后自动认为它是double类型。可以在后面加f,如1.2f,来指定它为float类型的数据。
#include<stdio.h> int main() { //整形除法 int a = 7 / 2;// 得 3 printf("%d\n", a); //三种写法都是浮点型除法 //除号的两个操作数有一个为浮点型是,结果就是浮点型,但要放在浮点型类型中存储,float或double double b = 7.0 / 2; //double b = 7 / 2.0; //double b = 7.0 / 2.0; printf("%lf", b);//以%f格式(或%lf)输出 得 3.5 }
3.2 位移操作符和位操作符
位移操作符 | 位操作符 |
>> | & |
<< | ^ |
| |
由于这些操作涉及到二进制位,我们后期文章讲
3.3赋值操作符
赋值操作符 |
= |
+= |
-= |
*= |
/= |
&= |
^= |
|= |
<<= |
>>= |
这里操作符用法几乎相同,涉及二级制位的操作符我们后期讲
int main() { int a = 0; a = 10;//= 赋值操作符 a = a + 5;//等价于下面这一行 a += 5;//复合赋值,既相加,有赋值 a = a - 2;//与下面等价 a -= 2; a = a * 3;//与下面等价 a *= 3; a = a / 2;//与下面等价 a /= 2; return 0; }
3.4单目操作符
有一个操作数的操作符叫单目操作符
! | 逻辑反操作 |
- | 负值 |
+ | 正值,一般省略不写 |
& | 取地址 |
sizeof | 操作符的类型长度(以字节为单位) |
~ | 对一个数的二级制按位取反 |
-- | 前置、后置-- |
++ | 前置、后置++ |
* | 间接访问操作符(解引用操作符) |
(类型) | 强制类型转换 |
!操作符:
//C语言如何表示真假 //0 假 //非0 真 //-1 真 #include<stdio.h> int main() { int a = 5; if (a)//a为真,进入if { //... } if (!a)//a为假,进入if { //... } printf("%d\n", !a);//输出0 printf("%d\n", !!a);//输出1 假0的反操作为真,真为1 return 0; }
-负号操作符:
#include<stdio.h> int main() { int a = -5; int b = -a; printf("%d\n", b);//输出5 }
sizeof操作符:
#include<stdio.h> int main() { int a = 100; //sizeof 是一个操作符 //sizeof 计算的是变量占用内存的大小,单位是字节 printf("%d\n", sizeof(a));//计算变量的大小 输出4 printf("%d\n", sizeof a);//这里括号可以省略,与函数不同。函数括号不能省略,说明sizeof不是函数 printf("%d\n", sizeof(int));//可以计算类型所占内存的大小 输出4 //printf("%d\n", sizeof int);//报错 //sizeof计算变量大小时括号可以省略,计算类型大小时不可以省略 return 0; }
++操作符:
#include<stdio.h> int main() { int a = 1; //a=a+1; b=a; int b = ++a;//前置++,先+1,后使用 printf("a = %d b = %d\n", a, b);//输出 a = 2 b = 2 //b = a; a = a + 1; b = a++;//后置++,先使用,再+1 printf("a = %d b = %d\n", a, b);//输出 a = 3 b = 2 return 0; }
--操作符:
#include<stdio.h> int main() { int a = 3; int b = --a;//a=a-1;b=a; printf("a = %d b = %d\n", a, b);//2 2 a = 3; b = a--;//b=a; a=a-1; printf("a = %d b = %d\n", a, b);//2 3 return 0; }
#include<stdio.h> int main() { int a = 5; printf("%d", a--);//5 printf("%d", a);//4 return 0; }
(类型)操作符:
#include<stdio.h> int main() { int a = 3.14;//3.14是小数,属于浮点型数据。将它存放在整形变量中会有警告。a最后为3 int b = (int)3.14;//强制类型转换为int,只保留整数部分 printf("%d\n", a);//输出3 return 0; }
3.5关系操作符
== | 相等 |
!= | 不相等 |
> | 大于 |
< | 小于 |
>= | 大于等于 |
<= | 小于等于 |
int main() { int a = 2; int b = 3; if (a == b) printf("a==b"); else printf("a!=b"); return 0; }
3.6逻辑操作符
&& | 逻辑与 |
|| | 逻辑或 |
逻辑操作符
逻辑与 && --> 并且 两个操作符都为真,才为真。又要有一个为假,则为假
逻辑或 || --> 或者 两个操作数只要有一个为真,则为真,两个同时为假,才为假
int main() { int a = 3;//非0为真 int b = 5; int c = 0; if (a && b)//非0为真 ,结果为真 { //-- } if (a || c)//真 { //-- } if (a && c)//假 { //-- } return 0; }
3.7条件操作符
又称三目操作符
语法:exp1 ? exp2 : exp3 exp为表达式
当exp1为真,exp2执行 ,exp2为操作符的结果
当exp1为假,exp3执行 exp3为操作符的结果
int main() { int a = 0;//初识化变量,最开始变量是内是个随机值,赋初值是好的编程习惯 int b = 0;//初识的值可以随意设置 scanf("%d %d", &a, &b); int m = 0; if (a > b) m = a; else m = b; printf("%d\n", m);//m是a和b中最大的值 //上面if else语句等价于 (a > b) ? (m = a) : (m = b); printf("%d\n", m); //还等价于 m = (a > b ? a : b);//将较大值赋值给m printf("%d\n", m); return 0; }
3.8逗号操作符
语法:exp1,exp2,exp3,....expn 可以有多个表达式,但表达式之间要用逗号分开
int main() { int a = 3; int b = 2; int c = 5; //逗号表达式,是从左向右依次计算的,逗号表达式的结果是最后一个表达式的结果 int d = (a += 3, b = 5, c = a + b, c - 4); // a=6 b=5 c=11 7 //注意:不是只算最后一个 printf("%d\n", d);//输出7 return 0; }
3.9下标引用,函数调用和结构成员
[ ] | 数组[ ] 如arr[10] |
( ) | 函数调用 |
. | 访问结构体成员 |
-> | 指针访问结构体成员 |
下标引用操作符[ ]
int main() { int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; //下标 0 1 2 3 4 5 6 7 8 9 //下标引用操作符 [] printf("%d\n", arr[5]);//[]是一个操作符,也有两个操作数arr 和 5 return 0; }
函数调用()
int Add(int x, int y) { return x + y;//返回表达式的结果 } int main() { int z = Add(3, 5);//()函数调用是都需要加(),()为函数调用操作符 操作数为Add 3 5 printf("haha\n");//printf函数使用时也要加()函数调用操作符 操作数为printf "hehe" return 0; }
4常见关键字
注:关键字,先介绍下面几个,后期遇到讲解
auto 自动
int main() { int num = 0;//局部变量是进入作用域创建,出了作用域销毁,自动创建、自动销毁 //所以局部变量为 auto int num = 0; //所有局部变量都有auto所以都省略了 return 0; }
break 终止 分支语句。
char double float int long short 数据类型
const 修饰类型 常属性
continue 继续
default 默认
do 在do..while循环中使用
else 在if..else 选择语句中使用
enum 枚举类型
extern 声明外部符号
for for循环中使用
register 寄存器关键字 可以修饰变量
return 函数的返回
signed 有符号的 修饰类型
unsigned 无符号的 正数 修饰类型
sizeof 计算变量或者类型的大小,单位字节
static 静态的
struct 结构体类型 自定义类型
typedef 类型重定义 重命名
union 联合体类型 自定义类型
void 无、空类型 函数的返回值 函数的参数 修饰指针
volatile 很少见,这里不讲
while while循环语句
关键字typedef
顾名思义是类型定义,这里应该理解为类型重命名
typedef unsigned int u_int;//u_int 的作用跟 unsigned int 的作用相同 ,相当于起了别名 typedef unsigned long long u_ll; int main() { unsigned int num = 0; u_int num2 = 0;//unsigned int 类型 u_ll num3 = 0;//long long 类型 return 0; }
关键字static
用来修饰变量和函数的
1.修饰局部变量 称为静态局部变量
2.修饰全局变量 称为静态全局变量
3.修饰函数 称为静态函数
void test() { int a = 5;//每次调用函数重新创建a a++;//a的地址不会改变,可能是编译器做了优化 printf("%d ", a);//输出10个6 }//每次调用完这个函数a就会被销毁 int main() { int i = 0; while (i < 10)//循环10次 { test(); i++; } return 0; }
1.static 修饰局部变量的时候
本来一个变量是存放在栈区的,被修饰后就存储到静态区了
static 修饰局部变量,改变了变量的存储类型(位置),使得这个静态变量的生命周期变长了,直到程序结束才结束
作用域不变
void test() { //静态变量 static int a = 5;//static修饰后,这个变量在编译阶段就已经创建,在整个程序执行完毕后才会被销毁 //F10 调试 F11进入test函数,在调试会发现会跳过上面这条语句。说明该变量在程序执行前就已经创建好 a++; printf("%d ", a);//输出6到15 }//每次调用完这个函数a就会被销毁 int main() { int i = 0; while (i < 10)//循环10次 { test(); i++; } return 0; }
c/c++代码学习中,我们把內存大概分为3个区域
栈区 存放 局部变量 函数的形参 临时作用的变量都是在栈区
特点 : 进入作用域创建,出了作用域销毁
静态区 存放 全局变量 静态变量
特点 :创建好后直到程序执行完毕才会被销毁
堆区 存放 动态函数分配 用malloc calloc realloc free等关键字
2.static 修饰全局变量
全局变量具有外部链接属性,在其他源文件内部依然可以使用(方法要正确)
声明外部符号
声明类型和名称
static 修饰全局变量改变了这个全局变量的链接属性,有外部连接属性变为内部连接属性
这个静态文件只能在自己所在的源文件内部使用,不能在其他源文件内部使用了
感觉作用与变小了,但存储位置不变
下图为add.c 与test.c 两个源文件
3.static 修饰函数
static 修饰函数和static修饰全局变量是一样的
函数是具有外部连接属性的,但是被static修饰后,就变成了内部连接属性
使得这个文件只能在自己所在的源文件中使用,不能在其他文件内部使用
寄存器 register
寄存器 字节为单位 电脑有几十个寄存器
高级缓存 几十个MB
內存 6/16/32G
硬盘 512 1T
网盘 2T
从下往上 数度变快, 造价变高,空间变小
寄存器可以让程序效率更高
int main() { //register 仅仅是建议的作用 //建议放在寄存器中,但是不是真的放在寄存器中,取决于编译器 register int num = 10; return 0; }
#define定义常量和宏
1.#define定义标识符常量
#define M 100//M 就是标识符常量 值为100 int main() { int arr[M] = { 0 }; int m = M; printf("%d\n", sizeof(arr));//400 100个大小为4个字节的元素 printf("%d\n", M);//100 printf("%d\n", m);//100 }
2.#define定义宏
与函数相似
#define ADD(x,y)((x)+(y)) //ADD宏的名称,(x,y)宏的参数,(x+y)宏的内容,实现体 //int 返回类型 Add函数名称 int x,int y 函数参数 int Add(int x, int y) { return x + y;//函数体 } int main() { int a = 10; int b = 20; //1.宏 int c = ADD(a, b); //替换为 int c = ((a) + (b); printf("%d\n", c);//输出30 //2.函数 int d = Add(a, b); printf("%d\n", d);//输出30 return 0; }
谢谢观看,感谢支持!!