第二个小程序 摄氏度 与 华氏温度对 转化 转换公式: 摄氏度 = 5*(华氏度-32)/9
//将摄氏度转化华氏度的方法
main() {
int fahr,celsius;
int lower,upper,step;
lower=0; //温度表下线
upper=300; //温度表上线
step = 20; //步长
fahr = lower;
while(fahr<=upper) {
//公式 摄氏度*9/5+32 =华氏度
celsius = fahr*9/5+32;
printf("摄氏度:%d\t华氏度:%d\n",fahr,celsius);
fahr=fahr+20;
}
}
在c语言中 所有变量都必须在使用前进行声明 申明通常放在函数的起始处
声明是由 类型名 和 一个变量表组成
例如 int a,b,c
其中int 表示其后所列变量为整数 int 与float 类型的取值范围取决于具体的机器类型 比如 16位的机型 int 的取值范围为【-2^15,2^15-1】
32位的将会更高 【-2^32,2^32-1】
c语言中的基本数据类型:
int 整形
float 单精度浮点型
double 双精度浮点类型
char 字符--一个字节
short 短整型
long 长整型
c语言中基本类型的存储大小 取决于 机器的类型 比如 cpu是32位 还是64位 或是16位
float 与 double的区别
c语言中 float 与 double 都属于 对小数数据的展示 其区别在于 两者的精度不同
#include <math.h>
showData() {
float pi_f = M_PI;
double pi_d =M_PI;
printf("float pi=%.20f\ndouble pi=%.20f",pi_f,pi_d);
}
M_pi=3.141592 653589793 23846
pi_d=3.141592 653589793 10000 double类型精确到小数点后面15位
pi_f=3.141592 74101257320000 float 类型精确到小数点和面6位
这里精确地位数与不同的编译器 以及计算机有关
int k = 5 int z= 3 int w = 5/3; ----->>w=1 (1.66666) 事实是int去尾法 将小数点后面的值全部忽略 只取整数
float w_f = 5/3 = 1.666666 精确的值需要用float类型来存储
输出语句:
%d 按照10进制整型数打印
%6d 按照10进制整型数打印 至少6个字符宽度
%6f 按照浮点数打印 至少占6个字符宽度
%.2f 按照浮点数打印 小数点后打印两位小数
%6.2f 按照浮点数打印 小数点后打印两位小数 至少占6个字符的宽度
while循环
while(循环条件){
//需要执行循环的代码
}
while 1.判断是否满足循环条件 满足进入{}中执行代码 不满足 不进入循环
2.执行 循环{} 中的代码
3.执行{}中的代码 后 再次判断是否满足 终止条件
特点 先判断 后执行 条件的改变在{}中自行设置
for语句
main(){
int fahr;
for(fahr =0;fahr<=300 ; fahr = fahr+20 ){
printf("摄氏度:%6.1f 华氏度%d\n",(5.0/9.0)*(fahr-32),fahr);
}
}
//这里 在第一个站位符 %6.1f的位置 我们对应的是值的表达式 即 (5.0/9.0)*(fahr-32)
for循环 是对while循环的改进 更加的直观
for(A初始化循环变量;B判断变量值是否满足判定条件;C变量值 一般是加上或减去步长){
// 循环体内需要执行的代码
}
for 循环的执行步骤 : 1. 初始循环变量 执行A
2. 执行B 判断循环变量是否满足判定条件 满足 执行{} 中的代码 不那满足直接终止并退出循环
3.{} 执行完毕 执行C
4. 回到 2 处 执行 B 依次执行 直到条件不满足 终止
for 循环与 while 循环可以 互相替换
特点都是先判断 后执行 在判断再执行
for 循环将 循环变量 以及循环条件 循环条件改变的方式 在 for语句的()全部展示出来 更直观 更容易让人看懂整个循环是如何进行以及终止的
打印 1-10
int i = 1;
while(i<=10){
printf(" %4d\n",i);
i=i+1;
}
for(int i=1;i<=10;i=i+1){
printf(" %4d\n",i);
}
如果 while 中的代码 有 10行以上 我们就不太好找 i的步长变化(一眼看不到),我们需要把{}中的方法代码阅读完毕 当然你可能说自己经验丰富可以倒着找 但是这样是有风险的 因为 可能在 条件变化未必只出现在结尾
for循环的则一目了然
符号常量
常量一般存储一些不经常改变的值 比如 math.h 标准库中的 pi
定义规则 #define 名字 替换文本
#define LOWER 0 /* lower limit of table */ 首先这里不需要指定 值(替换文本)的类型 其次 结尾不需要 ; 分割符
声明范围应该放在 类中 而不是 方法的域中(虽然可以在方法域中使用但是 这样define 将毫无意义)
这里需要注意 常量的类型 由后面的值决定
例如 #define LOWER 0
#define HEIGHT 30.1111 height 属于 float类型
输入/输出
getChar( ) 与 putChar(int value) 一次读入/写出一个字符 (注意一次,多次效果不是这样)
c = getChar( ); //当输入字符串时 可以使用getchar()读取其中的每一个字符
putChar(int value) 将整形变量 的内容以字符的形式打印出来
例如代码
int c;
while(c!='\n'){ //当getchar 获取的是最后的enter键时视为 结束标识
c= getchar(); //存储getchar()返回的字符
putchar(c);//在屏幕上输出 c字符
}
循环可以 将输入控制台的 字符 在次显示在控制台上 就像复制一样 输入什么 显示什么 但是真正的问题在于 getchar 输入的为字符串时每次读取的数据 不是首个字符 而是下一个字符 即在循环中可以自动读取每一个字符 神奇
计数
1、++nc--------> nc=cn+1;
2、nc++--------> nc =cn+1;
在不存储nc 值时 基本上没有区别
在存储 nc 值时 区别就体现出来
int nc =6;
int k = nc++; k=6; //nc++ 将nc的值赋值给k 在将nc进行++处理 即 nc = nc+1
int w = ++nc; w = 7; //先加加 即nc = nc+1 nc=7 再将nc赋值给w 即为 w=7
nc-- ---------------》 nc = nc-1;
--在未赋值情况下nc=nc-1 赋值情况看--在前在后 同++一致
逻辑计算符 == || &&
A==C 表示 A与C两个值是否相等
C语言中 int 值与 char 可以进行 互换 直接进行== 比较
这里是因为 当 c语言中使用 int k== 'c'; 其实是将 'c' 转换为 ASCII值与 k 进行对比
通过上表 我们可以看出 c字符的ASCII值为 99 当 int k>'c' 即被转换为 k>99
char c;c = c+1; 则时间 c转换为 99+1 =100 在将 100 因为存储100时使用的 是char 类型 100 会被转换为 d 字符 (d的 ASCII 值为100) char a ='c'; char c='d'; a>c 比的也是ASCII值
||逻辑或 条件1 | | 条件2 | |..... 有一个条件为真(成立) 那么命题(判断即为真)
int k =0; int c=1;
if( c<0 || k==0 ){ //成立 可以执行 {} 中的代码
}
&&逻辑与 条件1 && 条件2 &&.... 所有条件都为真(成立) 那么命题才成立(判断即为真)
int k =0; int c=1;
if( c<0 && k==0 ){ // 不成立 不可以执行 {} 中的代码
}
if (条件){ // 条件语句 如果 条件成立 即执行{}中的代码
}
引申形式
if( 条件){ //成立 执行 if后面{ } 中的代码 不成立 执行else{ } 中的代码
------;
}else{
=====;
}
if (条件){ //这种形式 谁的条件成立 执行谁和面{} 中的代码
}else if (条件){
}else if (条件){
}
if (条件){ //这种形式 谁的条件成立 执行谁和面{} 中的代码 如果都不成立 执行 else里面的代码
}else if (条件){
}else if (条件){
}else{
}
数组
声明语句 int ndigit[ 10 ]; 格式类型 名称 [size] size 为长度
int 数组存放数据的类型
ndigit数组名 [10]
数组存放数据的数量
初始化 int data[] = {1,3,4,5} //直接对数组进行赋值
或者 int data[10]; //不赋值进行初始化 告诉计算机为数组开辟多少空间
函数
int power(int x,int y){
int value=x;
for(int i=0;i<y;i++){
value=value*x;
}
return value;
}
函数组成:
返回值类型 函数名 (....参数){
语句序列
return 值; //如果没有返回类型 就不需要 return方法
}
return 关键子的出现意为着 函数执行的退出 return 可已在任何函数中使用 终止并返回该函数所需返回的值,或者如果不许返回值 那么return 主要是起到终止函数执行的作用
当方法调用时 我们 必须保证我们输入的方法名没有问题 同时 参数要符合创建的函数对的标准要求 否则会报错
power(0.5,9);//这是无法调用 power方法 因为 参数1 的类型与函数要求不符
参数--传值调用
c语言中,所有函数参数都是"通过值"传递的 (指针传递除外 指针相当于引用 指向数据存储的地址 ,修改改地址下的内容是会影响主函数中 对应变量的值)
传递给调用函数的参数值存放在临时变量中,而不是存放在原值中
main(){
int c = 5;
add(c);----------------》即使 add 方法将 c +1; 但是 add 中的 c 与 main 中的 c 是两码事儿 没啥关系
printf("-----------c------>%d",c); -------------> main 中 c的值 依然为 5;
}
add(int c){
c= c+1;
}
字符数组
c语言中的字符串是以字符数组的形式给出的
比如:char str[] = "abcd";
char str[] = {'a','b','c','d'}; //{}中放置字符元素
这两种形式是等价的
char str[6] = "hello" str的长度设置为6 为什么不是5呢?
因为 在c语言中 字符串结尾时会被自动添加上"\0" 作为字符串的结束标识符
hello在内存中以 hello\0 存在
所有已当我们设置字符数组是 长度为字符串长度+1
如果我不加1呢 char str[5]="hello" 这就出现问题了 在控制台打印是数据发现长度不是5 而是8 打印字符串发现乱码
这里需要注意 即使我们设置 char str[6] = "hello" 我们打印时他的真是长度 依然为5 \0 是不会被计算到长度中的
这里我们先不考虑指针....
外部变量与作用域 (extern : 外部)
局部变量
作用域 { } 将代码作为区域分割开来 ,在函数体{}定义的变量叫做局部变量 因为他只能在函数{}中使用 其他函数无法直接访问 其函数中定义的变量同理,只有自身可以直接访问
生命周期 局变量在方法执行时存在 执行完即被销毁
函数中的每个局部变量只在函数调用时存在,在函数执行完退出时消失。这也是其它语言通常把这个变量称为自动变量的原因 以后我们使用自动变量代表局部变量
外部变量(全局变量)
在函数体外定义的变量
生命周期与程序相同
所以我们要控制好全局变量的生命周期
在理解这个问题前我们先要理解搞清楚 声明与定义的区别
定义变量: 用于为变量分配存储空间 还可以为变量指定初始值 程序中变量有且只有一个定义;
声明变量:用于向程序表明变量的类型和名称
定义也是声明 extern 声明不是定义
变量在使用前就要声明或定义 在一个程序中 变量只能定义一次 可以声明多次
定义分配空间 声明不分配空间
这里需要注意 c语言中 声明是使用关键字 extern 实现的 这是核心区别
定义可以在函数内也可以在函数外 :1. 在函数外 变量为全局变量 2.在函数内成为局部变量
我们来看下声明和定义的区别
int k; 定义 未初始化
int k = 0; 定义 已经初始化
extern int k ; 声明
当全局变量在不同文件(.c)中被定义后 ,他文件在定义就会出现程序报错 一个变量指定被定义一次
我们要么重新定义的 变量 , 要么 需要已经在其他文件中定义的变量
这是就需要声明 告诉程序 该变量已经被定义过了 我现在要拿着直接用
声明的作用: 告诉程序 声明的变量已经在内存中存在 我要直接使用
比如这样
这里需要注意 extern 进行声明时 可以不加类型
同时 局部变量是可以w为名进行 定义的
c语言中全局变量的定义与局部变量的定义是不冲突的
补充 c语言中允许 全局变量 先声明使用 后定义 例如
在函数中使用 extern 只能对变量进行声明 不能直接进行初始化
在函数中进行 extern int UI =10 ;是不允许的 程序会直接报错