比特C语言初学者,大白话将知识通俗化,形象化复习理解;

        好的,在愉快的第一节复习之后,我们马不停蹄的来到第二节复习,下面进入我们的正式内容。

        上一节我们听到了整型,字符串,字符,你可能还见过浮点型,那么问题就来了:这是个煞(啥)?那还有%c、%d、%s、%f.....这是嘛玩意,别急,这一讲我们慢慢道来。

(不好意思,因为还没有去学博客编辑的格式,所以我不会加目录,各位看的时候请不要厌烦)

——---数据类型

  1.         我们说,用编程语言向计算机下达指令,从而解决我们的问题。要解决问题,从小学数学的应用题我们就知道,肯定先要读题,但计算机又读不懂文本咋办?那就需要用编程语言先将问题描述出来,怎么描述问题呢?对于问题中不同的信息,我们就给它们分类让计算机识别。欸,我们的数据类型就这么出来了。

在此处呢,我们先讲内置类型,自定义类型之后再说(因为我还没学)。

1.整型:先理解为整数的类型;

2.字符型:就是敲一下键盘,它所对应的符号;

3.浮点型:小数(小数点是可以左右浮动的,所以叫浮点型);

4.布尔型:判断真假,使用时要包含头文件     <stdbool.h>       布尔类型的值只有 true 和 false

(C语言中,也可以用  0 表示假,非0表示真)

————signed 和 unsigned

        顾名思义,signed 表示有符号的(正数默认不会打正号),unsigned表示无符号的,这俩兄弟是用来修饰 整型和字符类型的。我们前面已经说过,字符在数据储存中是用二进制数字表示的,字符本质上也是数字,所以也可以用这俩表示。至于浮点型,你直接打出来就可以了,不需要这俩玩意。

那么,既然都有signed了,为什么还需要一个unsigned呢,有符号就可以表示所有的数了啊?

这是因为,signed unsigned 储存数据的大小有限且相同,如果你只需要打非负整数的内容(如身高,体重)unsigned就可以显示多一倍的数据,因此才会特意分出来。

————数据类型的长度

        既然提到了储存数据的大小,我们就顺便说一嘴数据类型的长度。

        每一种数据类型都有自己的长度,长度的不同,储存数据的范围就不同。

为了更直观的看数据类型的长度,在这里我们介绍 sizeof 这个操作符,当然,它也是一种关键字sizeof 是专门用来计算数据类型的长度的,长度单位是字节。(在这里请注意,最小长度单位是bit比特,1字节 = 8 比特)

#include <stdio.h>

int main()
{
    printf("%zd\n" , sizeof (数据类型) );
    
    printf("%zd\n" , sizeof 表达式 );

    int i = 5;
    printf("%zd\n", sizeof i );

    printf("%zd\n", sizeof 5 );
    return 0;
}

如图,我想说明的是:sizeof 的格式

数据类型必须带小括号

表达式,创建的变量(就是int 后面跟着的 a ),具体字符(数字,字母..)是可以不用带上小括号的(打不打都行);

但是!! 

#include <stdio.h>

int main()
{
    int a = 0;

    printf("%zd\n", sizeof (a + 5));
    
    printf("%zd\n", sizeof a + 5);

    return 0;
}

所示的两个 sizeof 中:

                                第一个计算的是      a+5   ;

                                第二个计算的是      a ;算完a后得到的值,再加上5!!!

所以,为了避免这些杂七杂八的问题,我建议不管打什么都带一个小括号,反正打出来你看得也舒服,也能避免意想不到的错误。

注:sizeof 中表达式不计算

#include <stdio.h>
int main()
{
    
    printf("%zd\n", sizeof( 5 = 4 + 6 ));

    printf("%zd\n", sizeof ( 5.0 = 4 + 2 ));

    return 0;
}

在图中显示的这个表达式中,sizeof 只判断左边的那个数据是什么类型,然后打出它的类型。其余的计算式 如 (4 + 6)(4 + 2)是不会管的。

我在这里不采用鹏哥说的截断的说法,因为我个人认为这样理解有点麻烦(也可能是我学得太浅,还不明白它其他的用法),我的理解是:

————sizeof 只看你等号左边是什么类型,输出对应类型的长度,完事。

————不同的数据类型

        在每一个数据类型之中,其实还有更精细的划分。

比如说:  int   short int(缩写为short)    long int(缩写为long)   long long int (缩写为long long)      这些都属于整型类型

                float  double  long double                          都属于浮点类型

        (每一项中还可以加上signed unsigned,具体的这些我们不纠缠,要用的时候我们再展开讲,先清楚这些东西大概是用来做什么的,之后随着学习的深入,我们再去探究。

那在同一个类型中,用什么来区分呢?————数据类型的长度

#include <stdio.h>
int main()
{
    printf("%zd\n", sizeof (short) );
    printf("%zd\n", sizeof (int) );
    printf("%zd\n", sizeof (long) );
    printf("%zd\n", sizeof (long long) );
    printf("%zd\n", sizeof (float) );
    printf("%zd\n", sizeof (double) );
    printf("%zd\n", sizeof (long double) );

    return 0;
}

在输入图中代码之后,我们运行程序就可以得到结果了。

这里要注意的是,有时会出现两个相同数据类型的长度相等的情况

比如:   int 和 long 两个输出的结果都为 4(或者其他两个同类型的数据长度相同),这难道就是说long 和 int 长度一样,没有区别吗?

不是这样的。 long 的结果与它的前一位 int 相同,表示的是 long >= Int 的关系,long实际上不止4位。

————数据类型的范围

        既然我们都知道了数据类型的长度,那么必然要提到它们的范围。通过查阅它们的取值范围,我们才可以知道在什么场景下更适合使用哪一种数据类型。

                limits.h ⽂件中说明了整型类型的取值范围。

                float.h 这个头⽂件中说明浮点型类型的取值范围。


————二.变量

——1.变量的概念

        在小学应用题中,我们读了题就直接能做了吗?还不够。我们需要找到未知数和已知条件的等量关系,用x,y,z这样的变量表示未知数,从而写出方程,计算结果。

        计算机也一样,我们给它确定了数据类型,但具体要表示一个未知量,就要创建一个变量去表示它。

类型就是所创建变量的种类

int x = 0;

在这一行中,我创建了 x 这个变量,那 x 能表示什么类型的数据呢? 前面的 int 就是 x 表示的数据种类,它表明 x 是一个整型类型的变量。

有变量,相应的就有常量,常量与我们熟知的一致,就是 100 ,20 这些数。

——2.变量的分类

    全局变量:在大括号外定义的变量,可以在整个项目中使用(不同文件中需要用一定方法使用)

    局部变量:在大括号内定义的变量,只能在同一个大括号内使用

如图,现在我们在大括号外和大括号内同时创建了变量 x(可以重名,只要你分得清)

        在大括号内的printf 函数会打谁呢?

#include <stdio.h>

int x = 1;
int main()
{
    int x = 2;    
    printf("%c\n", x );

    return 0;
}

当然是自己人 x = 2,即局部优先。

这些语言最早是美国人玩得最6,那么命名习惯是根据他们熟知的东西,局部优先就像美国这个国家一样,州内的事情,联邦敢过多干涉吗?管不了一点。)

——算术操作符

        涉及运算,就离不开我们的数学符号了。加减乘除加上取余,但是这些熟知的符号,我们可以发现比如➗就没有出现在我们的键盘上,×(乘号)也没有,取余运算我们也没有天天在后面加个(mod),为什么呢?——因为效率太低了,➗其他地方能用吗?✖ 容易和 字母 x 弄混,mod就更是了,能直接用符号表示何必写那么多呢?

所以,编程中,+ - 保持不变,至于 ✖,我们用 *(星号)代替,➗ 用 / 代替 ,mod 用 % 代替,这样不仅效率提升了,这几个符号也都能用在其他的地方,就不需要增加符号在键盘上了。

                +,-,*,/ ,% 这些两边都需要运算数的符号我们统称为双目操作符

既然有了双目操作符,那有没有单目操作符呢? ——有的,+(正号)-(负号)++就是。

正负号好理解,那++又是什么呢?别急小老板,听我娓娓道来。

#include <stdio.h>

int main()
{
    a = a + 1;

    a += 1;
    
    a++;

    ++a;
    
    return 0;
}

                你知道 +1 的四种写法是什么吗?请看图中,就是这四种。

        为什么要这么衍生呢?——最初,你是一个什么都不懂的小白,勤勤恳恳地打着第一种;当你打多了之后,“哎呀,怎么这么麻烦,缩一缩啦。” 于是,第二种就出现了;但是呢,既然都已经缩成这样了,那能不能再缩一点呢?最终,第三种和第四种就出现了。

其中,我们着重介绍后两种:前置++ 和 后置++

这两种++的本质都是在表达 a+1 ,但是其中别有洞天。

#include <stdio.h>
int main()
{
    int a = 0;
    int b = 0;

    printf("%d\n", b = a++);

    a = 0;      // 再让 a 的值为0
    b = 0;      // 再让 b 的值为0
    printf("%d\n", b = ++a);

    return 0;
}

        最后我们得到,第一次 b = 0 ; 第二次 b = 1; 而两次 a 的最终结果都是1。

原因就在于:前置++(++在前面) 是“先++,后使用”         后置++(++在后面)是“先使用,后++”

我们要打印 b 的值,第一次是 b = a++ (后置++),a 的值先赋给 b 后,a 自己再++;

                                第二次是 b = ++a (前置++),   a 的值先 +1 ,再赋给 b 。

那么在讨论完前置后置之后,刚刚我们又看到了赋值,接下来,我们就来探讨赋值的概念。

#include <stdio.h>

int main()
{

    int a = 0;

    a = 1;

    return 0;
}

        在刚开始创建变量时,我们会顺便给这个变量一个值,这个过程就叫初始化

        我们再次用 a =   的形式让 a 的值变为你想要的值(比如  a = 2 ;   a = 5 .....),再次给 a 一个值的过程就是赋值。

请注意:尽管直接写 int a ; 也可以,但是初始化是一种规范,如果不初始化,这个变量的值则是 任意值,并且在有的编译器上会报错,所以,养成好的书写习惯。

    a = c = b + 2;

{
    b + 2 = c;

    c = a;

}

        我们当然可以像连续运算一样,进行连续赋值,赋值是从右往左的顺序

图中大括号外和大括号内的含义是一模一样的,但是:从形式上来说,分开来打不仅更美观,而且也能节省你的脑力,所以推荐分开赋值。

++,+= 也是一种赋值操作符。

——强制类型转换

        顾名思义,这个操作就是强行把一个类型的数据转变为另一种类型。


    int b = (int)3.14 ;

这条语句的意思是:创建整型变量  b  等于 3.14 的整型形式,也就是让 b = 3。

强制类型转换固然可以使用,但是谁在可以敲个 b = 3 的情况下 , 非得给你来个强制类型转换,那真是抽象。

所以啊,我们都是在一些特殊的地方使用它,一般不用。


————printf函数

1.内涵

打印文本到屏幕上,以<stdio.h>为头文件

2.占位符(重点概念)

占位符,通俗来讲,就是你在初高中看语文书的时候,遇到一个不懂的词义或者典故,书上给你标出来的序号:

只不过,在C语言中,我们以 % 开头作为占位符的格式,以下是不同类型的占位符:

                %d : 整型占位符                                %c:字符型占位符

                %s : 格式串                                        %f :浮点型占位符

占位符格式

printf("There are %d apples",3);

%d 代表这里要用一个整型数值代替,在逗号后面写上参数3,这句话打印出来就是“那里有3个苹果”

printf("%c", );

一般情况下,占位符会忽略空格,但是%c不会,因为空格本身也是一个字符

可以打出多个占位符,但是后面的数值必须按照顺序写,以 "  ,  " 分隔

——3.限定宽度

在 % 的后面加上数字,就表示输出最小的宽度,默认右对齐

printf("%5d",123);

在此处,我们写了 %5d ,就代表输出的“123”要占5位,但是不够怎么办?就用右对齐的方式,将剩下的2个空位以空格替代。

如果想要跳过空格:

printf(" %c", assa);

在%c 的前面加上空格,就可以输出后面的内容了

如果想要左对齐,就输入%-5d,负号表示改变,也就是将右对齐变为左对齐

printf("%-5d",123);

——4.显示正负号

一般地,我们输入" +5 "的时候都会默认成"5",怎么样才能输出" +5 "呢?

printf("%+5d",123);

只需要添加 " + "即可。(负号是一定会显示的,所以不提及)

——5.限定小数位数

我们知道,小数默认会打印小数点后6位,但如果想要将 " 1.2 "不打成"1.200000",那该怎么办呢?

printf("%.2f",1.2);

在 % 的后面加上小数点,敲上你想要的位数即可。

当然,这几项是可以在一起用的

printf("%+5.2f",1.2);

打出来的结果就是   " +1.2"  

同时,我们也可以使用  *   来传参

printf("%*.*f",3,2, 4.65);

先把参数写好,再写想要打印的数字即可。

这里,相同的格式对于字符串来说,就是限制打出字符串的个数

printf("%.5s","hello world");

我们只能看到 "hello"的结果,因为.5  已经将我们打出的个数限制在5个


有了输出,那我们可不可以输入呢?当然可以!scanf函数就是专门解决这个问题的

————scanf函数

——作用:读取用户的键盘输入

程序运行时,scanf会根据占位符类型来读取你的输入,将其存入到内存空间之中

头文件也是<stdio.h>

 scanf("%d%d%f%f", &i, &j, &x, &y);

在这里,scanf会按照 整型、整型、浮点型、浮点型的顺序读取 i、j、x、y 四个数据,scanf在读取时,会自动过滤空白字符(换行符、空格)

但是,占位符的格式一定要和数据的格式保持一致!!!!

scanf("%d,%d,%d",&i &j &k);

这个例子中,双引号里占位符是以逗号隔开,但是数据之间是以空格隔开,这样造成的结果就是只能读出第一个数据,因为scanf 是根据占位符的格式一点一点读取你的数据。

scanf("%s %c %s %d",&a &b &c &d);

如果你在 c处填了整型,而c处需要的是一个字符串的时候,scanf 就会结束读取

——scanf 的返回值

在使用scanf 函数的时候,我们常常看到下面报错:"scanf 忽略返回值",虽然不理它,我们直接运行代码也能行。但这玩意究竟是个 "煞",在这里我们细细探究。

        1.概念

scanf 的返回值,指的是它读取了几个数据,如:读取了1个数据,就返回1;读取了2个,就返回2

如果没有读取任何数或者匹配失败,则会报 0 

如果在读取任何数据之前就发生错误,或者直接读取到文件结尾,则返回EOF(-1)                        EOF----- End Of File

我们可以按 ctrl + z 来得到 EOF 这个结果

        2.作用

我们使用scanf 的返回值来检验是否读取成功

        3.%s 的细微区别

%s scanf ,不能简单的等同于字符串。

它的规则是:从第一个非空字符开始读起,直到遇到第一个空白字符结束

这也就是说,我们不能使用它来打印单词、歌曲名、书名;另外,scanf 遇到%s 时,还会在末尾存储一个\0

        4.scanf 风险

实际上,scanf 最大的危险是它不会在意能装下多少,你输入多少,它就给你强行放多少。尤其是在数组中,这样的特点会导致我们的程序出错,所以我们必须要限制它:

#include <stdio.h>
 int main()
 {
 char name[11];
 scanf("%10s", name);
 return 0;
 }

使用%10s 表示我们只输入10个数据(因为scanf自动在末尾添加了 \0),这样就不会导致输入过多而崩溃。

        5.赋值忽略符

有时,由于疏忽,我们会忽略输入的一些小问题:

#include <stdio.h>
 int main()
 {
 int year = 0;
 int month = 0;
 int day = 0;
 scanf("%d-%d-%d", &year, &month, &day);
 printf("%d %d %d\n", year, month, day);
 return 0;
 }

在这里,我们的数据和占位符格式就不一致,我们该怎样避免错误呢?

#include <stdio.h>

 int main()
 {
 int year = 0;
 int month = 0;
 int day = 0;
 scanf("%d%*c%d%*c%d", &year, &month, &day);
 return 0;
 }

只需要在 % 的后面加上 *,就代表这个字符解读后可以忽略,我们就不需要在意这样的小细节了。

总结一下,在这节课中我们学习到了

        1.数据类型

        2.变量与操作符

        3.printf 函数相关内容

        4.scanf 函数相关内容

四个大内容,以及在这之下衍生的细节内容。这一节的内容才算是C语言的真正起步,虽然冗杂、繁多,但是只要你明白你是根据这四个大内容而学习具体知识,心里就不会乱。

虽然这些内容对于初学者来说很多,关系很乱记不住。但是逻辑和内核相当的简单,需要多敲多练,在不断练习代码之中掌握知识,不需要死记硬背,能用就行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值