1.1 C语言基础
-
C语言数据类型
-
重点
- 常量和变量,整型和实型
- 标识符命名,变量的定义和赋值
- 数据类型占用的空间
-
main函数,程序的起点
- #include "stdio.h" 表示头文件。std表示standard,IO就是input和output,h表示这个是头文件,#include 预编译处理指令可使头文件生效
- void main() // 是main函数,是程序的入口
- {} // 中间的函数体,是该函数具体的值
- ; // 表示是一句话的结尾,必须有
- /* */ 这个是注释。好像也支持java风格的单行注释。
-
变量
-
变量是用户定义的标识符,用于标识内存中的一个具体的存储单元,在这个存储单元中存放的数据称为变量的值。
- 变量名是大小写敏感的
- 必须不能以数字开头
-
变量的声明与赋值
- 声明与赋值可以放在一起,也可以不放在一起,但是都必须遵循先声明后赋值的形式。
-
一般规则
类型关键字变量名;
-
常见的声明赋值方式
- int a, b, c ;
- int a=0;b=0;c=0;
- int a=0;
-
int a;
a=0;
-
错误的赋值方式
- int a = b = c = 0;
-
以下这种连续赋值的方式也是错误的
main(){
int a; /*这里是正确的,因为是第一位*/
a = 0 ;
float f; /*这里是错误的,f必须在第一条可执行语句之前定义*/
f = 3.5;
}
-
-
数据类型
<<C语言基础 - 电子表格.xlsx>>
- 有符号和无符号长度上的区别是将符号位当成符号位还是数据位。只用int数据类型才会被各种usignerd,short,long等修饰
- 定义整型变量时,只要不指定无符号型,默认就是有符号的。
- 一般而言float能保证7位有效数字,double类型能保证16位有效数字。
- 注意,c中是没有布尔类型的概念的。
-
变量或数据类型占用的空间大小
- 内存中的存储单元是一个线性地址表是按字节(Byte)进行编制的。
- 1字节等于8个二进制的位(bit),bit就是binary digit二进制数的缩写。位是衡量物理存储器的最小单位。一个二进制位能表示的只能是0或1。为了表示更多的信息,将8位连接一起表示数据,所以其表示方位0-255之间。有时为了表示更大的范围,我们通常使用2个字节(16位,比如Unicode码)来表示。
- 进制之间的转换
-
英文名称 |
中文名称 |
换算 |
bit(b) |
比特(位) |
|
Byte(B) |
字节 |
1B=8b |
KB |
|
1KB=1025B |
-
查看当前系统的数据类型长度
- 由于C没有规定每个字节的长度,因此不同的系统的字节的长度是不一样的。
- 我们使用sizeof()关键字来看当前系统数据的某种数据类型的长度。sizeof()是关键字,并非函数。
-
具体实例
printf("char %d\n",sizeof(char));
-
不同进制的数据表示
- 通常0开头的表示8进制
- 通常0x开头的表示16进制
-
运算符与表达式
- 只需要一个操作数的成为一元操作符,需要两个两个操作数的成为二元操作符,需要三个操作数的成为三元操作符。
-
整数触发和浮点数除法(Java中也是这样的)
- 12/5 结果是2,因为C中整数除以整数结果还是整数
- 12.0/5结果是2.4,因为只有除数或被除数中有一个是浮点型,才会使结果想上转型,给出浮点型的结果。
-
常量
-
为什么使用常量
- 因为硬编码和幻数是程序的可读性变差,可维护性变差。
-
宏常量
#include <stdio.h>
# define PI 3.14
main() {
double r;
printf("Input r:");
scanf("%lf",&r);
printf("circumference = %f\n",2*PI*r);
}
-
const常量
# include <stdio.h>
main() {
const double PI = 3.14;
double r;
printf("please input r:");
scanf("%lf",&r);
printf("circumference = %f\n",2*PI*r);
}
-
宏常量
-
宏定义 # define 标识符字符串
- 宏定义中没有数据类型
- 标识符(变量名通常是大写的。所有的常量都应该是大写的)
- 定义宏是不能使用=号的。
- 最后不能以分号结尾。因为宏不是语句,而是预编译指令
- 宏替换:自动将程序中宏标识符替换为宏的值
- 宏常量没有数据类型,编译器不对宏常量进行类型检查,只是进行简单的类型替换(甚至我们可以使用宏将关键字替换成中文,实现中文编程),容易出现各种问题。
-
-
const常量
- 定义在代码中,格式如下: const 数据类型标识符 = 值;
- 有效的避免了宏常量中的各种问题。
-
-
类型转换
- 可以将小范围的值赋给大范围的值,这是安全的。将大范围的值赋给小范围的值会有警告,因为精度有丢失。
-
强制类型转换
-
(float)(2/3)
- 尽管看起来这个程序返回的float,但实际上是将结果转换成float返回。所以结果是0.00000
-
-
常用标准数学函数
- 在使用数学函数时,必须加上头文件 #include <math.h>
- 常见数学函数
函数名 |
功能 |
sqrt(x) |
求平方根 |
fabs(x) |
求绝对值 |
pow(x,y) |
计算x的y次方 |
-
输入与输出
-
转意符
- "123\n" 长度是4,因为\n也占一位,是一个字符。实际上每个ASCII字符都占用1位
-
各种符号的ASCII码值
- 在ASCII中,A比a小32.
-
字符 |
ASCII码值 |
0 |
48 |
A |
65 |
Z |
90 |
a |
97 |
z |
122 |
-
字符的输入与输出(专门用来输入输出字符)
- getchar() // 输入,不能接收处参数
- putchar() // 输出,一次只能输出一个字符
-
示例:
#include <stdio.h>
/*
* 功能:练习getchar()和putchar()的使用
* 实现输入小写字母,将小写字母转换成功大写字母
*/
main(){
char a;
printf("please input a word:");
a = getchar(); // getchar不能接受参数,只能返回
char b = a - 32;
putchar(b); // 输出转换成功的大写字母
putchar('\n') // putchar()只能输出一个字符。不能输出字符串
}
-
数据的格式化输出
-
函数printf()的一般格式
printf(控制字符串);
printf(控制字符串,输出参数列表);
- 常用的格式化字符串
-
格式化 |
解释 |
%% |
输出一个% |
%c |
输出一个字符 |
%d |
输出一个十进制的数字,正号省略 |
%f |
输出小数。实数部分全部输出,默认输出6位小数。如果在前面加数字表示域宽(主要用于对齐,跟输出的位数没有关系),输出宽度大于设置的域宽,按实际输出,小于设置的域宽,则使用空格补齐。精度(.2)就是在点后加数字表示精度。精度和域宽可以单独使用。 |
%s |
输出字符串 |
特殊修饰符 |
l对数字类型就行修饰时,就是各种的长型比如%lf,%ld等 |
-
实例
#include <stdio.h>
/*任务
* 各种输出的测试
*/
main(){
double d = 3.141592657;
printf("直接输出:%f\n",d);
printf("带域宽的值:%3f\n",d);
printf("输出带小数点的值:%.2f\n",d);
printf("输出带域宽和小数的值:%1.2f\n",d);
printf("%f\n",d);
printf("%3f\n",d);
printf("%.2f\n",d);
printf("%11.2f\n",d); // 域宽主要用来对齐,而不是控制数据长度的
}
输出结果:
直接输出:3.141593
带域宽的值:3.141593
输出带小数点的值:3.14
输出带域宽和小数的值:3.14
3.141593
3.141593
3.14
3.14
-
数据的格式化输入
-
一般格式
scanf(控制字符串,参数地址列表);
参数地址列表通常使用 & 开头,表示取地址值。
-
常用的格式化字符串
- 基本等同printf()的内容
-
格式化字符 |
解释 |
%c |
输入一个字符,空白符,回车,制表符等都算有效输入 |
%s |
输入字符串。遇到空白符时,系统认为读入结束 |
* |
表示忽略后面的值 |
- 此时的域宽的意义是截取几位,不在时printf()的含义了。
- 此时的精度是没有意义的,scanf()是没有办法指定输入的精度的。
-
输入的结束
- 遇到空格,回车符,制表符
- 达到输入的域宽
- 遇到非法的字符输入
-
使用实例
-
按照程序的分割符进行输入
scanf("%d,%d",&a,&b); // 我们应该时输入12,34这种情况,因为scanf中试是逗号作为分割符,所以数据中也应该使用相同的符号作为分割符
scanf("a=%d,b=%d",&a,&b); // 输入时:a=12,b=34
-
按照域宽分割
scanf("%2d%2d",&a,&b); // 如果输入的是1234,则a=12,b=34。因为设定的域宽就是2
-
忽略作为分割符
scanf("%d%*c%d",&a,&b); // 这个时候可以是任何字符作为ab之间的分割符
scanf("%2d%*2d%2d",&a,&b); // 这个时候,如果输入123456,其中a就是12,b就是56;
-
-
%c在使用中的一个问题
- 原因:空格,回车,指标符都是一个char,所以如果存在这样的字符也会被char来获取。
- 解决:在获取字符输入的时候使用getchar()或者scanf(" %c",&a)在获取之前加个空格将数据放弃掉。但是这种解决只是针对只有一个空白符的。使用fflush(stdin),会强制输出缓存中的内容,然后就不会有什么