目录
前言
本篇幅从0开始学习c语言
软件建议:Visual Studio
先了解八大基本数据类型(必背):
byte:字节
int:整型
long:长整型
short:短整型
char:字符型
浮点数:
float:单精度
double:双精度
boolean:布尔型
c中所有变量必须在开头都定义好
变量命名规则:只能包含数字、英文、_,可以组合但不能以数字开头
最好见名知意
不能是C语言的关键字
第一个c程序
#include <stdio.h>
int main() {
printf("hello world!");
return 0;
}
如上代码是什么意思呢,我们一句一句解释
#include <stdio.h> -----> 引入头文件
···头文件:用于声明常用的函数、变量、宏等,
#include
指令的作用是将指定的头文件内容插入到当前代码中···stdio.h:头文件,以.h结尾,是c语言里的标准头文件
int main(){} ---> 主函数,一切程序的运行都是从主函数开大括号开始到收大括号结束,int是定义返回值类型
printf---->输出语句
return:程序结束时返回值,
第一节、输出语句
没有哪一个c程序是用不到输出语句的,几乎所有。所以输入和输出语句尤其重要。
printf()输出和scanf()输入都包含在stdio.h头文件中,所以几乎所有c程序都需要引入这个头文件。
printf函数的原型为:printf(const char *format, ...)
下面讲解printf的三种格式:
#include <stdio.h>
int main()
{
int i = 10;
int j = 20;
//1.printf("字符串\n")
printf("hello world\n");//---/n表示换行
//2.printf("输出控制符",输出参数)
printf("%d\n",i);//---%d输出整形,其余的下面具体介绍
//3.printf("输出控制符1输出控制符2...",输出参数1,输出参数2...)
printf("%d %d\n",i,j);//两个%d之间的空格是可以输出的,本质上双引号包围的是字符串,只不过%d是可以被识别的占位符
return 0;
}
1.输出控制符
看起来很多其实非常好记,基础部分一定要沉住气!!!
1.%d:按十进制整型数据的实际长度输出-----输出int类型变量/数字常量
2.%ld:输出长整形----输出long类型变量
3.%md:
m为制定的输出字段的宽度,数据长度不足m前补0,超过m则原样输出
例:m=5:1234567,输出的就是1234567;111输出的就是00111
4.%u:输出无符号整型(unsigned),%d是有符号的
5.%c:用来输出一个字符----char类型变量
6.%f:用来输出实数,包括单精度和双精度---- float和double类型的变量,默认输出最多六位小数,超出部分四舍五入
7.%.mf:输出实数时保留m位小数,不足m位小数部分的后补0,遵循四舍五入,“.”不能省略
例如:12.345:%.2f=12.35;%.6f=12.345000
8.%o/%O:以八进制整数形式输出----日常生活中我们都是逢10进1,八进制就是逢8进1,八进制的10=十进制的8
9.%s:用来输出字符串
10.%x/%X/%#x/%#X:十六进制输出整数,十分重要
一定要掌握这四个,因为调试的时候经常要将内存中的二进制代码全部输出,然后用十六进制显示出来,下面写一个程序看看他们四个有什么区别:
#include <stdio.h>
int main()
{
int i = 47;
printf("%x\n",i);//2f
printf("%X\n",i);//2F
printf("%#x\n",i);//0x2f
printf("%#X\n",i);//0x2F----绝对标准的十六进制写法
return 0;
}
由此可见,%x和%X的区别就是结果里的f是大写还是小写,#号的作用就是输出的是标准的十六进制写法,测试代码中最后一个写法是绝对标准的十六进制写法。
2.如何输出"%d"、"\"、双引号
如果单纯的把这三个符号放在双引号里,会被c语言解析,那我又想让它原样输出怎么办?这里就用到转义符---输出%d只需要在前面再加一个%,输出“\”和“""”只需要在前面加“\”
#include <stdio.h>
int main()
{
printf("\\, %%d, \"\"\n");
return 0;
}
第二节、输入语句
scanf的功能用一句话概括就是:通过键盘给程序中的变量赋值
scanf函数的原型是:scanf(const char *format, ...)
它有两种格式:
#include <stdio.h>
int main()
{
int i;
//1.scanf("输入控制符",输入参数)
scanf("%d",&i);//不支持在双引号里写其他文字。“&”是取址符
printf("i=%d\n",i);
return 0;
}
#include <stdio.h>
int main()
{
int i;
//2.scanf("输入控制符 非输入控制符",输入参数)
scanf("i=%d",&i);//因为printf中字符串都是原样输出,所以scsanf里就要原样输入
printf("i===%d\n",i);
return 0;
}
放上不原样输入的结果
原样输入的结果
所以不建议在输入语句中加入非输入控制符,因为完全没必要🐶
如果有多个变量怎么办呢?scanf是可以一次给多个变量赋值的:
#include <stdio.h>
int main()
{
int i;
int j;
int k;
//2.scanf("输入控制符 非输入控制符",输入参数)
scanf("%d%d%d",&i,&j,&k);//因为printf中字符串都是原样输出,所以scsanf里就要原样输入
printf("i===%d,j===%d,k===%d\n",i,j,k);
return 0;
}
强调一点!!!!!输入的时候,双引号里写多个输入时,不要加逗号!!!不要忘记输入的时候变量时取它的地址给它符值,取址符万不能忘!!!
输入和输出不论是个数还是顺序都是一一对应的,这样的错误程序不会给你报错,如果结果和你想的不一样,就想想是不是参数少写了🐶
输入和输出的数据类型一定要和变量的类型一致,程序不会报错但是结果可能就不是我们想要的了。
如果输入的时候想要文字提示,那就在scanf函数的上一行写一个printf语句,绝对不支持在scanf里写提是文字哦。
第三节、运算符和表达式
这里只介绍四个运算符:
算数运算符
关系运算符
逻辑运算符
赋值运算符
表达式是不带分号的,带分号的是语句。表达式是指用运算符连接起来的、有意义的式子。
1.算数运算符
1.和小学数学一模一样的:+、-、*(乘)
2./(除):在c语言中除法的运算结果和数据类型有关,如果两个数都是int,结果舍去小数只保留整数部分作为结果,两个数有一个是浮点数,那结果就是浮点数。
2.%:取余-----输出的是计算后的余数
3.++:自增
4.--:自减
自增和自减到循环的时候再做解释。
#include <stdio.h>
int main()
{
int i = 10;
int j = 3;
double k = 3.0;
printf("两个整数相除的结果是:%d\n",i/j);
printf("两个整数取余的结果是:%d\n",i%j);
printf("整数和小数相除的结果是:%f\n",i/k);
return 0;
}
2.关系运算符
1.和数学一模一样的:>,<,>=,<=
2.!=:不等于
3.==:等于,注意一个“=”表示的是符值,i=3就是把3赋给变量i
3.逻辑运算符
1.&&:逻辑与---表示并且,全真为真,一假全假
2.||:逻辑或(短路或)---表示或者,全假为假,否则为真,执行过程中遇到真那后边的判断就不执行了,直接返回结果真。
3.!:逻辑非---取反,真变成假,假变成真
1表示真,0表示假
多用于判断
从别的地方找了一张图,这个真的很简单,就不多解释了
4.符值运算符
1.=:右边的值赋给左边的变量
2.+=:i+=3 == i=i+3;
3.-=、*=、/=:和+=一样
5.运算符的优先级
挺难记住的,如果没有考试会考这个,写程序的时候把你想先运算的加个括号就行了,括号是优先级最高的。
简单的记忆:
()>!(逻辑非)>算数运算符>关系运算符>&&>||>赋值运算符
第四节、流程控制
流程控制算是c语言整个框架第一个重点。对于C++,Java,C#都是要学习的知识,在所有高级语言中都是一模一样的。
1.概念
什么是流程控制?----程序怎么执行,程序以什么顺序执行
流程控制可以分为:
顺序执行:就是从上到下依次执行
选择执行:就是分支语句了;比如日常买东西,低于十块钱就买,高于十块钱不买,有两个或以上选择
循环执行:代码反复执行;
2.选择执行:
if(表达式){
代码块1;
}else{
代码块2;
}
#include <stdio.h>
int main()
{
int i;
printf("请输入0或1:");
scanf("%d",&i);
if (i==0) {
printf("i love you!\n");
}else{
printf("sorry\n");
}
return 0;
}
if(表达式1){
代码块1;
}else if(表达式2){
代码块2;
}else{
代码块3;
}
如果代码块只有一条语句,那么可以省略大括号
if(...)
...
else:
...
if可以没有else单独使用:if(...){...},但是else不能脱离if单独使用
#include <stdio.h>
int main()
{
int i;
printf("请输入整数:");
scanf("%d",&i);
if (i == 0) {
printf("i love you!\n");
}else if(i == 1){
printf("sorry\n");
}else{//除了输入0和1,其他的都执行的是else语句中的代码块
printf("i don`t know what you say.\n");
}
return 0;
}
switch(表达式){//绝对不能是实数,即小数
case 常量表达式1:
代码块1;
break;
case 常量表达式2:
代码块2;
break;
........
default://默认输出语句,相当于else,可以不写
代码块n;
break;
}
break:结束这段程序。如果下面有别的程序就执行下面的程序
#include <stdio.h>
int main()
{
int i;
printf("请输入整数:");
scanf("%d",&i);
switch (i) {
case 1:
printf("i love you!\n");
break;
case 2:
printf("sorry\n");
break;
default:
printf("i don`t know what you say\n");
break;
}
return 0;
}
如果不写break:
布置一个小作业吧,写一个程序,输入成绩判断是优秀、良好、及格和不及格,记得做严谨的判断,比如分数不能是负数,不能超过满分
注意:程序不识别 3<i<10,只能写成:3<i&&i<10
3.循环执行
循环执行分三类:
for循环
while循环
do...while循环
while和do...while能做的for都能做
3.1、for循环
一般形式:
for(变量名 = 初始值;变量名 关系运算符 目标值;变量名步长 ){
语句;
}
关系运算符只用:>,<,>=,<=
步长:对变量进行加减乘除的运算,就像上台阶一样,你一步上或下几个台阶,上一个就是i+=1,上两个就是i+=2。上面省略的i++和i--就是步长为1,上楼梯和下楼梯的区别。
注意:括号里的东西用分号隔开,最后一个没有分号
#include <stdio.h>
int main()
{
int i;//c语言的所有变量必须在开头声明,后面才可以使用
for (i = 0; i<10; i++) {
printf("%d\t",i);
}
return 0;
}
++和--:
i++和++i,i--和--i单独使用时是一样的
如果放在运算中
a = i++ ==> a = i, i = i + 1//先赋值,后自增,
a = ++i ==> i = i + 1, a = i//先自增,后赋值。
记忆方法:++在前先算++,加加在后后算++。
自减与自增用法一样
for循环的扩展很灵活,比如嵌套for循环,for循环里写分支语句,下面写一个九九乘法表,自己理解一下吧
#include <stdio.h>
int main()
{
int i,j;
for (i=1; i<10; i++) {//外层循环控制行的输出
for (j=1; j<=i; j++) {//内层循环控制列的输出
printf("%d * %d = %d\t",j,i,i*j);//确定了行和列那这里就是单元格啦
}
printf("\n");//输出完一行之后进行换行,才能达到阶梯三角形的效果
}
return 0;
}
3.2、while循环
格式:
while(表达式){
语句;
}
解释:当表达式为真,执行循环体(整个循环叫循环体)
所有的while都可以写成for循环,反之亦然
#include <stdio.h>
int main()
{
int i = 1;
while (i < 10) {
i++;
printf("i=%d\t",i);
}
return 0;
}
3.3、do...while()循环
它和while唯一的区别就是无论是否满足条件它都会执行一次,用的不多,主要用于人机交互。
do{
语句;
}while(表达式);
#include <stdio.h>
int main()
{
int i = 10,j = 10;
while (i < 10) {
i++;
printf("i=%d\t",i);
}
printf("\n");
do{
j++;
printf("j=%d\t",j);
}while(j<10);
return 0;
}
注意:如果循环终止条件写的不对,那就成了死循环,一直执行永不停止。
在循环中,结束整个循环用break,结束本次循环用continue。
比如循环要执行100次,但是到第50次你的目的就达到了,那就写个判断,在第50次就结束循环,用break
从0-100循环,逢5或倍数跳过,否则输出一条语句,那就可以在输出前判断是不是5或倍数,是的话就continue,这样这一次循环就结束了,开始进入下一次循环。
#include <stdio.h>
int main()
{
int i = 0,j = 0;
while (i < 10) {
i++;
if (i == 5) {
break;
}
printf("i=%d\t",i);
}
printf("\n");
while (j < 10) {
j++;
if (j == 5) {
continue;
}
printf("j=%d\t",j);
}
return 0;
}
3.4、补充:清空输入缓存区
所有从键盘输入的数据,不论是自符还是数字,都是先存在内存中的一个缓存区中,叫作“键盘输入缓冲区”,简称“输入缓存区”或“输入流”
为什么要清空缓存呢?当我们输入多个变量的时候,按下回车之后scanf才将输入的内容存储到内存,包括回车。那回车就算是一个char类型的变量值了,如果我输入的两个变量一个是int,一个是char,以回车隔开,那取的时候,char的值就变成回车了,就不是我输入的那个了,以下程序可以自己运行一下,根本不给你输入char的机会,c直接变成了回车
#include <stdio.h>
int main()
{
int i;
char c;
printf("请输入一个整数和一个字符:");
scanf("%d",&i);
scanf("%c",&c);
printf("i = %d\n",i);
printf("c = %c\n",c);
return 0;
}
那该怎么办呢,有三个办法
1.另外定义一个变量去处理回收输入的“垃圾”
2.getchar();
3.fflush(stdin);用法与getchar一样,但是功能更强大,直接将输入缓存区全部清空
#include <stdio.h>
int main()
{
int i;
char ch;
char c;
printf("请输入一个整数和一个字符:");
scanf("%d",&i);
scanf("%c",&ch);//回收上一个输入的回车
scanf("%c",&c);
printf("i = %d\n",i);
printf("c = %c\n",c);
return 0;
}
#include <stdio.h>
int main()
{
int i;
char c;
printf("请输入一个整数和一个字符:");
scanf("%d",&i);
getchar();
scanf("%c",&c);
printf("i = %d\n",i);
printf("c = %c\n",c);
return 0;
}