本文已参与「新人创作礼」活动,一起开启掘金创作之路
文章目录
一、C语言的执行
-
一般情况下,C语言程序从main()开始执行
- 从左花括号 { 开始,到右花括号 } 结束
-
默认情况下,C语言程序以自上而下的顺序执行
- ·执行的基本单位是语句,每条语句使用分号 ; 隔开
-
C程序为单纯的文本文件,无法直接执行
-
C程序编译后可生成二进制可执行程序
二、程序中的数据输出
-
C语言内置了很多实用的工具包
-
工具包有一个固定的名字,通过名字进行使用(#include)
-
每个工具包都提供了非常多的小工具可以使用,如:
- stdio.h工具包提供了一个“打印机”工具printf
- printf 通过正确设置后,能够在屏幕上打印文本
编辑
-
打印参数解析
- printf的使用规则:先设置打印参数,再指定打印文本
- c语言中的字符串是被双引号(” ”)括起来的字符序列
-
深入理解printf 打印参数
-
printf使用数据对参数中的格式化字符进行替换(%s 等)
-
不同类型的数据对应于不同的格式化字符
- %s 对应字符串,%d对应整数,%f对应浮点数,等等
-
最终的打印数据是一个字符串
-
编辑
简单上个代码及输出结果
#include <stdio.h>
int main()
{
printf("%s\n", "Hello, world!");
printf("%s = %d\n", "1 + 1", 1 + 1);
printf("AutumnZe\n");
return 0;
}
编辑
三、数据类型与变量(上)
-
C语言根据数据的特点进行了分类
- 整数类型:不带小数点的数据类型,-1,0,1,2
- 浮点数类型:带小数点的数据类型,如-0.55,0.0,3.14
- 字符类型:英文字符类型,如'D','T', '\n’(字符数据使用单引号括起来)
-
再看printf 打印
-
不同类型的数据对应于不同的格式化字符,%s 对应字符串,%d对应整数,%f对应浮点数,等等(printf 中的格式化字符其实是指明需要打印的具体数据的类型)
- printf("%d\n",2); //打印整数2
- printf("%f\n",2); //打印浮点数2
- printf("%c\n",2); //打印字符2
-
同一个数据(如:数字2)可能有不同的解读方式,因此,必须显示的指出对应的数据类型,否则可能造成错误的运行结果。
-
C语言数据类型
-
整型数的细分类型
- short :表示的范围-32768 ~ 32767
- int :表示的范围-2147483648~ 2147483647
-
浮点型数的细分类型
- float :表示的范围-3.410^38~ +3.410^38
- double :表示的范围-1.710^-308~1.710^308
-
编辑
四、数据类型与变量(下)
-
C语言中命名的规则
- 字母(a-z,A-Z)数字(0-9)或下划线( _ )构成的字符序列
- 第一个字符必须为字母或者下划线(不能为数字)
- 大小写不同,变量也不相同
编辑
-
程序中的变量赋值
- 定义:改变变量所代表的值的操作叫做赋值操作
编辑
-
程序中的变量初始化
- 定义:在创建变量的同时,显示指定一个初始值
编辑
-
强调说明
- 程序中的赋值(=)不是数学中的等于
- 创建变量的同时指定初始值的操作叫做初始化(int i = 1;)
- 创建变量之后改变其值的操作叫做赋值(int i; i = 1;)
- 没有初始化的变量,其值为随机数
- 约定俗语:创建变量 <----> 定义变量
小结:
- 命名必须遵循规则,否则会编译出错
- 定义变量之后可以改变其代表的值(赋值)
- 定义变量的同时可以指定一个值(初始化)
- 赋值和初始化是不同的两个操作(虽然相同的符号)
- 程序中的赋值(=)与数学中的等于完全不同
五、深入数据类型与变量
-
程序中数值的类型
-
程序中的数值(字面量)也有类型:默认类型或指定类型
- ·默认类型:2为int, 0.2为double, 'c'为char
- ·指定类型:0.2f 为float(后缀f表示 float)
-
下面上一段代码,强调类型的重要性
#include <stdio.h>
int main()
{
int a = 50000;
short b = 0;
int i = 0;
float f = 0.2;
printf("a = %d\n", a);
printf("b = %d\n", b);
printf("\n");
b = a;
printf("a = %d\n", a);
printf("b = %d\n", b);
printf("\n");
b = 30000;
a = b;
printf("a = %d\n", a);
printf("b = %d\n", b);
printf("\n");
printf("\n");
printf("i = %d\n", i);
printf("f = %f\n", f);
printf("\n");
f = 3.14f;
i = f;
printf("i = %d\n", i);
printf("f = %f\n", f);
return 0;
}
输出结果如下,通过输出结果,我们可以得到下面这些结论
编辑
-
结论
-
大类型赋值给小类型时,可能发生溢出
- 当数值在小类型范围内→赋值成功
- 当数值超过小类型的范围→发生溢出
-
小类型可以安全的赋值给大类型
-
浮点类型赋值给整型,会发生截断(小数部分丢失)
-
整型赋值给浮点类型,能够成功完成
-
-
类型转换
- C语言中不同类型的变量之间(变量与值)之间进行赋值或运算时,会发生类型转换。类型转换不改变原变量的值。
-
小知识
-
开发环境(编译软件)由编辑器和编译器组成
- 编辑器:负责程序的编写工作(字处理软件)
- 编译器:负责程序的编译工作(文本变为二进制)
-
C语言编译器检查类型的同时,可能做默认转换
-
编辑
-
强制类型转换(显示类型转换)
- C语言中可以进行强制类型转换
- 语法规则: type name = (type)var;
- 示例:
编辑
程序中应该尽量避免不同数据类型之间的转换
上一段代码感受一下,值得注意的是,i 为 int 类型,而 b 为 short 类型,short 表示的范围-32768 ~ 32767,所以就算强制转换,printf 输出的值也肯定不对!!
#include <stdio.h>
int main()
{
int a = 50000;
short b = 0;
int i = 0;
float f = 0.2;
i = 40000;
b = (short)i;
printf("i = %d\n", i);
printf("b = %d\n", b);
printf("\n");
f = 3.1415f;
a = (int)f;
printf("f = %f\n", f);
printf("a = %d\n", a);
return 0;
}
下面为输出结果:
编辑
下面再看一段代码, 感受强制类型转换在四舍五入中的应用:
#include <stdio.h>
int main()
{
float f = 1.49f;
float r = 0;
r = f + 0.5f;
r = (int)r;
printf("f = %f\n", f);
printf("r = %f\n", r);
return 0;
}
下面为输出结果:
编辑
小结:
- 不同类型的变量(值与变量)赋值时,会发生类型转换
- 类型转换不会改变原来变量的值
- 类型之间可表示的范围不同,因此类型转换可能造成错误
- C语言中能够显示进行类型转换(强制类型转换)
- 程序中应该尽量避免类型转换
六、程序中的输入
- stdio.h 工具包提供了一个数据输入工具scanf
- scanf通过正确设置后,能够获取键盘输入的数据
- scanf 将键盘获取的数据“填入”变量
- stdio.h中 scanf 的使用示例
编辑
-
注意事项
- scanf 中的格式化字符不能包含其它无关字符
- scanf 中的格式化字符必须与对应的变量类型一致
下面通过一段程序感受一下键盘输入
#include <stdio.h>
int main()
{
float i = 0;
printf("i = %f\n", i);
scanf("%f", &i);
printf("i = %f\n", i);
return 0;
}
下面为输出结果:
编辑
再来看一段输入两个数相加的代码:
#include <stdio.h>
int main()
{
int i = 0;
int j = 0;
int k = 0;
printf("Input 2 numbers to add:\n");
scanf("%d%d", &i, &j);
k = i + j;
printf("%d + %d = %d\n", i, j, k);
return 0;
}
下面为输出结果:
编辑
小结:
- stdio.h工具包提供了输入工具scanf
- scanf 通过正确设置后能够从键盘输入数据到变量中
- scanf 中的格式化字符必须与对应的变量类型—致
- scanf能够连续输入数据到不同的变量
七、signed 与 unsigned
先看一段代码:
#include <stdio.h>
int main()
{
short s = 32767;
int i = 2147483647;
short ss = -32768;
int ii = -2147483648;
printf("s = %d\n", s);
printf("i = %d\n", i);
s = s + 1;
i = i + 1;
printf("s = %d\n", s);
printf("i = %d\n", i);
printf("ss = %d\n", ss);
printf("ii = %d\n", ii);
ss = ss - 1;
ii = ii - 1;
printf("ss = %d\n", ss);
printf("ii = %d\n", ii);
return 0;
}
下面为输出结果:
编辑
实验结论
程序运行时,如果发生了越界:
- 大于类型最大值,则:运行结果回转到最小值附近
- 小于类型最小值,则:运行结果回转到最大值附近
-
有符号与无符号
-
整型数据可以主动声明其“符号特性”
- signed int,范围为:-2147483648 ~ 2147483647
- unsigned int,范围为:0 ~ 4294967295
-
-
注意事项
- signed int 和 unsigned int 所能表示的整数个数是一样的,仅最小值和最大值不同。
-
整型的扩展知识
-
signed 和 unsigned 可与 char 和 short 组合使用
- signed char, unsigned char
- signed short,unsigned short
-
程序中可能出现的关于 int 的缩写
- signed <--> signed int
- unsigned <--> unsigned int
-
下面看一段代码:
#include <stdio.h>
int main()
{
unsigned char uc = 128;
char c = 128;
unsigned ui = 2147483648;
signed i = 2147483648;
printf("uc = %u\n", uc);
printf("c = %d\n", c);
printf("ui = %u\n", ui);
printf("i = %d\n", i);
return 0;
}
下面为输出结果:
编辑
- 小结(常用整型大盘点)
常规写法 | 完整写法 | 表示的数据范围 |
char | signed char | -128 ~ 127 |
unsigned char | unsigned char | 0 ~ 255 |
short | signed short | -32768 ~ 32767 |
unsigned short | unsigned short | 0 ~ 65535 |
int | signed int | -2147483648 ~ 2147483647 |
unsigned int | unsigned int | 0 ~ 4294967295 |
八、再论数据类型
-
C 语言中的 sizeof 关键字
-
功能:用于获取类型或者变量所占用的内存大小(字节)
-
用法:
- sizeof ( type )
- sizeof ( variable )
- sizeof variable
-
-
数据类型与内存
- 不同的数据类型(变量) 会占用不同大小的内存
- 同一种整型的有符号与无符号版本占用相同内存
类型 | 占用内存 |
char | 1 |
short | 2 |
int | 4 |
float | 4 |
double | 8 |
下面看一段代码:
#include <stdio.h>
int main()
{
int c = sizeof(char);
int s = sizeof(short);
int i = sizeof(s);
int uc = sizeof(unsigned char);
int us = sizeof(unsigned short);
int ui = sizeof(unsigned int);
printf("c = %d\n", c);
printf("s = %d\n", s);
printf("i = %d\n", i);
printf("sizeof(float) = %d\n", sizeof(float));
printf("sizeof(double) = %d\n", sizeof(double));
printf("uc = %d\n", uc);
printf("us = %d\n", us);
printf("ui = %d\n", ui);
return 0;
}
下面为输出结果:
编辑
-
C语言中的奇葩整型 (long)
- long 在使用不同编译器时,可能占用的内存不同
- long 通常占用 4 字节内存,也可能占用 8 字节内存
- long long 表示整型,固定占用 8 字节内存
- long long 是 long long int 的缩写形式
下面看一段代码:
#include <stdio.h>
int main()
{
long l = -1l;
long long ll = 21474836481ll;
printf("l = %ld\n", l);
printf("sizeof(long) = %d\n", sizeof(long));
printf("ll = %lld\n", ll);
printf("sizeof(long long) = %d\n", sizeof ll);
return 0;
}
下面为输出结果:
编辑
-
数据类型的本质区别
-
因为占用的内存大小不同,所以可表示的范围不同
-
不同类型的数据,在内存中使用不同的表示法
-
如:
- 正整数和负整数的表示法不同
- 整数和浮点数的表示法不同
-
-
小结
- 字面量(如:123,4.56)都有默认的数据类型
- sizeof 关键字用于获取类型或变量占用的内存字节数
- long 是一种奇葩的整型,占用4字节或者8字节
- long long 是在一个占用 8 字节内存的整型
九、变量经典问题剖析
-
补充知识
-
左值和右值
- 左值:可以出现在赋值符号左边的值,如:变量
- 右值:出现在赋值符号右边的值,如:变量,字面量
-
连续变量定义和连续赋值:
- type v1, v2,v3;
- v1 = v2 = v3;
-
浮点类型(float & double)对数据的表示是不准确的
-
整数类型(char, short, int, long)对数据的表示是准确的
-
浮点类型与整数类型在内存中对数据的表示法完全不同
-