目录
一、C语言基础
1.1 程序安装
Dev C++
1. 官方网站: https://sourceforge.net/projects/orwelldevcpp/
2. 创建新项目
3. 编写程序后,必须先编译再运行
4. 设置断点
即将要运行的代码,还未运行。
1.2 程序框架
在自定义函数前,代码必须满足如下框架:
#include <stdio.h>
int main()
{
代码行;
...;
...;
return 0;
}
1.3 变量
<类型名称><变量名称>;
① 变量名称只能由字母、数字、下划线组成,且数字不可以出现在第一个位置上。
② 关键字不可用作变量“标识符”
- 赋值和初始化:
① 所有变量在第一次被使用(出现在赋值运算符右边)之前都应该被赋值一次。
② 变量需一个一个赋值。
1.3.1 本地变量、局部变量(local)
1. 本地变量是定义在块内的
- 可以是定义在函数的块内
- 可以是定义在语句的块内
- 甚至可以随便拉一个大括号来定义变量
2. 程序运行进入这个块之前,其中的变量不存在;离开这个块,其中的变量消失。
3. 块外面定义的变量在里面仍然有效;
4. 块里面定义了和外面同名的变量则掩盖了外面的;
5. 不能在一个块内定义同名的变量。
6. 本地变量不会被默认初始化;参数在进入函数的时候被初始化了。
1.3.2 全局变量
1.4 常量
const int AMOUNT = 100;
常量的标识符一般全大写表示。
1.5 数据类型
(C99的类型)
1.5.1 整数
char 、 short 、 int 、 long 、 long long
整数的内部表达:
计算机内部一切都是二进制。
18 —— 00010010
-18 —— 如何表达?
补码
拿补码和原码可以加出一个溢出的“零”
对于-a,补码就是,其中n是这种类型的位数。
如:
对于一个字节(8位),可以表达的范围是: 00000000 - 11111111
其中:
- 00000000 表示 0
- 11111111 ~ 10000000 表示 -1 ~ -128(高位为1的数 作为纯二级制数时,11111111代表255,而作为补码时代表-1)
- 00000001 ~ 01111111 表示 1 ~ 127
unsigned
不以补码的形式来表示,看做纯二进制
扩展了表达的正数部分的数的范围,但不能表示负数了。
8进制和16进制:
- 一个以0开始的数字字面量是8进制
- 一个以0x开始的数字字面量是16进制
- %o 用于8进制;%x 用于16进制
1.5.2 浮点数
float 、 double 、 long double
输出精度:
在%和f之间加上.n可以指定输出小数点后几位,输出是做四舍五入的
如:
// 浮点数的输出精度
# include <stdio.h>
int main()
{
printf("%.3f\n",-0.0049);
printf("%.30f\n",-0.0049);
printf("%.3f\n",-0.00049);
return 0;
}
程序运行结果:
1.5.3 逻辑
bool
- 逻辑运算是对逻辑量进行的运算,结果只有0或1
优先级:
非! > 且&& > 或||
1.5.4 指针
1.5.5 自定义类型
浮点数和整数一起运算时,会默认把整数变为浮点数。
区别:
1. 类型名称不同
2. 输入输出时的格式化不同
- int —— printf("%d", ...) scanf("%d", ...)
- long —— printf("%ld", ...) scanf("%ld", ...)
- double —— printf("%f", ...) printf("%e", ...) scanf("%lf", ...)
- float —— printf("%f", ...) printf("%e", ...) scanf("%f", ...)
输出科学计数法的格式
3. 所表达的数的范围不同
char < short < int < float < double
4. 内存中所占据的大小不同
1个字节到16个字节(1字节 = 8比特 = 8位)
// 检查数据类型所占的字节数
# include <stdio.h>
int main()
{
printf("sizeof(char)=%ld\n",sizeof(char));
printf("sizeof(short)=%ld\n",sizeof(short));
printf("sizeof(int)=%ld\n",sizeof(int));
printf("sizeof(long)=%ld\n",sizeof(long));
printf("sizeof(long long)=%ld\n",sizeof(long long));
return 0;
}
程序执行结果:
- char —— 1字节 -128 ~ 127
- short —— 2字节 -32768 ~ 32767
- int —— 取决于编译器(CPU)
~
- long —— 取决于编译器(CPU)
- long long —— 8字节
5. 内存中的表达形式不同
整数 —— 二进制数(补码)
浮点数 —— 编码
sizeof
① 一个静态运算符,它的结果在编译时刻就决定了。
② 给出某个类型或变量在内存中所占据的字节数。
③ 不要在sizeof的括号里做运算,这些运算不会执行。
sizeof(int)
sizeof(i)
强制类型转换:
要把一个量强制转换成另一个类型,需要:
(类型)值
(int)10.2
(short)32
需要注意安全性。小的变量不总能表达大的量。
1.6 运算符优先级
自上而下优先级越来越低。
所有的关系运算符的优先级比算数运算符的低,比赋值运算符高。
1.7 复合赋值
//复合赋值例子
#include <stdio.h>
int main()
{
int a1 = 5;
int b1;
b1 = a1++;
printf("a1 = %d , b1 = %d\n", a1 , b1);
int a2 = 5;
int b2;
b2 = ++a2;
printf("a2 = %d , b2 = %d\n", a2 , b2);
return 0;
}
程序执行结果:
- b1存储的是a1++这个表达式的值,为a1本身=5;执行a1++后a1本身的数值加1变为6。
- b2存储的是++a2这个表达式的值,为a2+1后的值=6;执行++a2后a2本身的数值加1变为6。
count--和--count同理。
1.8 判断语句
1.8.1 if-else
1.8.2 switch-case
switch(控制表达式)
{
case 常量:
语句
...
case 常量:
语句
...
default:
语句
...
}
- case后接的常量必须是整数,不能是范围(可根据需求适当转换成整数)
- 分支标号case只是说明switch内部位置的路标,在执行完分支中的最后一条语句后,如果没有break,则会顺序实行到后面的case;直至遇到一个break,或switch结束。
1.9 循环
1.9.1 while
当满足条件时,不断地重复执行循环体里的内容。
(先判断循环条件是否满足,再执行循环体)
while( <循环条件> )
{
<循环体语句>;
}
1.9.2 do-while
在进入循环时不做检查,在执行完一轮循环体的代码后,再检查循环的条件是否满足。满足则继续下一轮,否则结束循环。
do
{
<循环体语句>;
}
while( <循环条件> );
区别:循环执行的判断条件的位置。且do-while一定会至少执行一次;而while可能一次都不执行。
1.9.3 for
for = 对于
1. 任何一个for循环都可以改写为一个while循环。
2. 先判断是否满足循环条件,再执行循环体。
for ( 初始条件 ; 循环继续的条件 ; 循环每轮要做的事情 )
{
<循环体语句>;
}
循环选择技巧:
- 循环有固定次数 —— for循环
- 循环必须执行一次 —— do-while循环
- 其它情况 —— while循环
1.9.4 循环控制
1. break
跳出循环
(无论循环还有几轮没执行,都不执行了,直接跳出循环)
2. cuntinue
跳过循环这一轮剩下的语句,进入下一轮
(无论这一轮循环剩下的还有多少语句没执行,都不执行了,直接进入下一轮的循环)
1.9.5 嵌套循环
1. 循环里面还有循环(任意循环模式)
2. 跳出嵌套循环
break & continue只能对它所在的那层循环做
解决办法:goto
跳到goto后面所指的位置(如跳到嵌套循环程序的最外层)
1.10 函数
1.10.1 调用函数
函数名(参数值);
- 没有参数也需要加()
- 有参数需要给出正确的数量和顺序,这些值会被按照顺序依次用来初始化函数中的参数。
- 可以传递给函数的值是表达式的结果,包括(只传值!!):
1. 字面量
2. 变量
3. 函数的返回值
4. 计算的结果
int a,b,c;
a = 5;
b = 6;
c = max(10 , 12);
c = max(a , b);
c = max(c , 23);
c = max(max(23,45) , a);
c = max(23+45 , b);
1.10.2 从函数中返回
return
- 停止函数的执行,并送回一个值
return;
return 表达式;
- 没有返回值的函数
void 函数名(参数表)
1. 不能使用带值的return,也可以没有return
2. 调用的时候不能做返回值的赋值
1.10.3 函数参数传递
C语言在调用函数时,永远只能传值给函数,变量不共享!!
每个函数有自己的变量空间,参数也位于这个独立的空间中,和其他函数没有关系。
1.11 数组
1.11.1 定义数组
<数组中每一个单元的类型>变量名称[元素数量];
如:
int grades[100];
double weight[20];
- 元素数量必须是整数
- 数组中的所有元素具有相同的数据类型
- 数组一旦创建,不能改变大小
- 数组中的元素在内存中是连续依次排列的
- 数组下标(索引)从0开始计数
- 出现 segmentation fault 错误,可能是数组越界了
数组的集成初始化
int a[] = {2,4,6,7,1,3,5,9,11,13,23,14,32};
// 定义一个长度为13的数组,第一个元素为2,其余全是0
int a[13] = {2};
- 适合初始数据稀疏的数组
1.11.2 数组运算
- 数组变量本身不能被赋值。
- 如果需要把一个数组的所有元素交给另一个数组,必须采用遍历。
数组遍历:
通常使用for循环,循环变量i 从0 到 < 数组的长度
1.11.3 二维数组
int a[3][5];
定义一个名为a的3行5列的矩阵。
二维数组的遍历:
for (i = 0; i<3; i++)
{
for ( j = 0; j<5; j++)
{
a[i][j] = i * j;
}
}
- a[i][j] 是一个int
- a[i][j] 表示第i行第j列上的单元
二维数组的初始化:
1. 列数必须给出,行数可以由编译器来数;
2. 每行一个{},用逗号分隔。如果省略,表述补零。