C语言的数据类型和变量

一、数据类型介绍

         生活中有各种数据,我们在C语言中要表示这些数据,就要用到数据类型,使用整型类型描述整数,使用字符类型描述字符,使用浮点型类型描述小数。类型其实就是说它们这些数据具有共同的特征,编译器只有知道了数据的类型才知道如何操作。

         那么我们就来盘一下C语言中内置的各种数据类型。

1.1字符型

char//character
[signed]char//有符号的
[unsigned]char//无符号的

1.2整型

//短整型
short [int]  //这里的int可以省略
[signed] short [int]  //这里的int可以省略
unsigned short [int]  //这里的int可以省略

//整型
int
[signed] int
unsigned [int]  //这里的int可以省略

//长整型
long [int]  //这里的int可以省略
[signed] long [int]  //这里的int可以省略
unsigned long [int]  //这里的int可以省略

//C99Z中引入更长的整型
long long [int]  //这里的int可以省略
[signed] long long [int]  //这里的int可以省略
unsigned long long [int]  //这里的int可以省略

1.3浮点型

float
double
long double

1.4布尔类型

        在C99标准之前是没有布尔类型的,都是使用整数0表示假,非零的整数表示真。C99后引入了布尔类型,用来专门表示真假。

#include<stdio.h>
#include<stdbool.h>
int main()
{
    bool flag = true;
    if (flag)
        printf("hhhhhhhh");
    return 0;
}

        布尔类型的使用得包含头文件<stdbool.h>  布尔类型变量的取值是:true或者false。

头文件中bool类型的定义

1.5数据类型的长度

        每种数据都有自己的长度,创建变量时,使用不同的数据类型,能够创建出长度不同的变量,变量长度不同,存储的数据范围就会有不同。

1.5.1sizeof操作符

        这个操作符是用来专门用来计算sizeof的操作符数的类型长度的,单位是字节。

sizeof操作符中的操作数可以是类型、变量和表达式。

sizeof (类型)
sizeof  表达式  //后面为表达式时括号可以省略

要注意的是:表达式中的是不真实参与运算的,根据表达式的类型来得出大小!

int a=2;
sizeof(++a);
printf("%d",a);

        上面的的这段代码输出是2还是3呢?很多小伙伴会认为输出的是3。其实不是,sizeof中的表达式是不参与计算的,它只返回类型的长度!原因是sizeof在代码进行编译的时候,就根据表达式的类型确定了,而表达式是在程序运行期间才能执行,在编译期间已经将sizeof处理了,在运行期间自然就不会执行表达式了~~~

1.5.2数据类型长度

二、signed和unsigned

        signed关键字,表示一个类型带有正负号,包含负值。

        signed关键字,表示一个类型不带有正负号,只表示0和正整数。

        对于int类型,默认是带有正负号的,也就是说inr和signed int是一样的。所以在创建变量时,signed一般直接省略,写了也不会说你错,但是能说明你很心细hh~~

        signed是可以省略的,但是unsigned就不能省略了,只表是非负整数时,就必需要使用关键字unsigned来声明变量。 unsigned的好处就是在相同的内存空间中,存储的最大整数值大了int一倍

        字符类型char也是可以设置signed和unsigned。但是要注意,C语言中规定char类型是否带有正负号,由当前系统来决定。也就是说char不等同于signed char,它有可能是signed char,也有可能是unsigned char。这一点与int不同,int等同于signed int

三、数据类型的取值范围

       数据类型有很多,每一种数据类型都有自己的取值范围,也就是存储数值的最大值和最小值的区间,这么多的的类型,我们就可以在适当的场景下选择合适的类型。如何查看当前系统不同数据类型的取值范围呢?

limits.h这个头文件中说明了整型类型的取值范围。

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

四、变量

4.1变量的创建

        前面讲了这么多关于数据类型的知识点,那么数据类型是用来干嘛的呢?是用来创建变量的。

        什么是变量?C语言中把经常变化的值称为变量,不变的值称为常量。

创建变量的语法:data_type  name;如下:

//变量的创建
int age;
char hh;
double high;

//变量在创建的时候,就给一个初始值,就叫做初始化。
int age=20;
char s='h';
double high = 180 ;

4.2变量的分类

4.2.1全局变量

        在大括号外部定义的变量就叫做全局变量。全局变量的使用范围更广,整个工程中都有办法使用。

4.2.2局部变量

        在大括号内部定义的变量就叫做局部变量。局部变量的使用范围比较局限,只能在自己所在的局部范围内使用。

PS:那如果全局变量和局部变量的名字相同呢?

        我们可以看到在上面代码的运行结果都是10,那就说明,再同名的时候,局部变量是优先使用的!

4.2.3全局变量和局部变量的存储(大致了解)

        学习C/C++语言的时候我们关注内存中的三个区域:栈区,堆区,静态区。

        局部变量存储在栈区                               

        全局变量存储在静态区

        堆区是用来动态内存管理的(后期慢慢介绍)

五、算术操作符:

        在我们写代码时,一定就会涉及到计算,为了方便匀运算,提供了一系列操作符,其中有一组就就叫做算术操作符。分别是+、-、*、/、%。这些都是双目操作符。

5.1 +  -

        +和-用来完成加法和减法。+和-都是有两个操作数的,位于操作符两端的就是它们的操作数,也就是双目操作符

5.2  *

        运算符*用来完成乘法,也是双目运算符。

5.3 /

        前两个运算符都比较简单,就不做过多的描述,但是这个运算符就大有讲究了。这个运算符是用来完成除法的。

5.3.1 /运算符要注意点

1.当除号的两端都是除法时,执行的是整数除法,得到的结果也是整数。

        尽管x的类型是float,但是输出结果仍是2,而不是2.5,原因就在于C语言里面的整数除法是整除,只返回整数部分,丢弃小数部分。

        那我们如何得到浮点数结果呢?两个操作数至少有一个是浮点数,C语言就会执行浮点数除法。

        我们来看一个典例:

//下面这串代码输出的结果是多少?
int main()
{
    int x=5
    x=(x/20)*100
    printf("%d",x);
    return 0 ;
}

        你经过运算后是不是觉得输出结果是25,但实际上输出的是0,x/20是整除,得到的结果是整数0,0*100后得到的结果是0。

        如果要得到你算出的结果,我们只需将20改为20.0,让其执行浮点数除法,就可以得到结果25。

5.4 %

        这个运算符会进行求模(余)运算,返回两个整数相除的余数这个运算只能用于整数,不能用于浮点数。

5.4.1负数求模规则

        结果的正负号由第一个运算数的正负号决定。

六、赋值操作符

        在创建变量的时候给一个值,叫做初始化,在变量创建好之后再给它一个值,叫做赋值。赋值操作符为=

int a=100;//初始化
a=66666;//赋值

6.1连续赋值

int a=11;
int b=22;
int c=33;
c=b=a+4;//从右向左依次赋值

        这样的代码不容易被理解,建议拆开来写,方便观察代码执行的细节。

6.2复合赋值符

        在写代码时,我们会=可能会对一个值进行自增,自减。

C语言中的复合赋值符。可以很方便的表示。复合赋值符有:

+=    -=    *=    /=    %=    

//下面的后期会讲解

>>=    <<=    &=    |=    ^=
int a=2;
a+=2;//等同于a=a+2;
a-=1;//等同于a=a-1;

七、单目运算符

        前面说到的都是双目运算符,有两个操作数。C语言中还有一些操作符只需要一个操作数,被称为单目操作符。++、--、+(正)、-(负)都是单目操作符。

7.1++  --

        ++分为前置++和后置++,--分为前置--和后置--。(前置指的是操作符在操作数前,后置指的是操作符咋操作数后)

7.1.1前置++

        口诀:先+1,后使用。

int main()
{
	int a = 10;
	int b = ++a;
	printf("%d\n", a);
	printf("%d\n", b);
	return 0;
}

        a原来是10,a+1后赋值给b,b就是11。此时a,b都是11。

7.1.2后置++

        口诀:先使用,后+1。

int main()
{
	int a = 10;
	int b = a++;
	printf("%d\n", a);
	printf("%d\n", b);
	return 0;
}

        a原来是10,先赋值给b,a然后在+1变为11。此时a=11,b=10。

.1.3前置--和后置--        前置--、后置--与前面的前置++、后置++是同理的,只是把+1换成了-1。

7.2+  -

        这里的+、-表示正负号,都是单目操作符。运算符+对正负没有影响,可以省略,写了也不会出错,运算符-可以改变一个值的正负号,就要用到我们常用的口诀:正负得负,负负得正。

八、强制类型转换

        操作符中有有一种特殊的操作符是强制类型转换。

int a=6.666;

        a是int类型,6.66是float类型,两边的类型不一致,编译器会报错。为了消除这个错误,我们就可以用到强制类型转换。

int a=(int)6.66;

        这样会将6.66强制转换为int类型,只取整数部分。强制类型转化到万不得已的时候才会使用,代码都我们手敲上去的,为什么不一步到位?给自己找麻烦呢?

九、printf        scanf 

9.1printf

9.1.1基本用法

        它的作用是将参数文本输出到屏幕上。f代表format(格式化),表示输出文本的格式。要注意的是使用printf时要引用<stdio.h>这个头文件,l里面定义了printf。

9.1.2占位符

        占位符,顾名思义,就是这个位置可以用其他值带入。

#include <stdio.h>
int main()
{      
    printf("我是%d个清澈愚蠢的大学生",1);
    return 0;
}

        在这个代码中,我是%d个清澈愚蠢的大学生  是输出文本,%d就是一个占位符,这个位置会被后面的1替换。占位符的第一个字符一律是%,第二个字符表示占位符的类型,%d表示这里必须要用一个整数来替换。最后的输出结果:我是1个清澈愚蠢的大学生。

        除了%d,还有很多的占位符,%s表示带入的是字符串。

#include <stdio.h>
int main()
{      
    printf("%s正在学习C语言","Q.__");
    return 0;
}

        我们可看到前面的占位符为%s时,printf函数的第二个参数就必须是字符串。打印出来的结果就是Q.__正在学习C语言。

        在一个输出文本内,我们可以有多个占位符,要注意的是:参数和占位符是一一对应的关系,第一个占位符为%d,那么printf函数的第二个参数就必须为一个整数。如果有n个占位符,那么参数就有n+1个。如果参数缺少对应的占位符,那么则会输出内存中的任意值。

9.1.3占位符举例

%a:十六进制浮点数,字母输出为小写。
%A:十六进制浮点数,字母输出为大写。
%c:字符。
%d:十进制整数。
%e:使用科学计数法的浮点数,指数部分的e为小写。
%E:使用科学计数法的浮点数,指数部分的E为大写。
%i:整数,基本等同于%d。
%f:小数(包含 float 类型和 double类型) 。
%g:6个有效数字的浮点数。整数部分一旦超过6位,就会自动转为科学计数法,指数部分的e为小写。
%G:等同于%g,唯一的区别是指数部分的E为大写。
%hd:十进制 short int型。
%ho:八进制 short int型。
%hx:十六进制 short int类型。
%hu: unsigned short int型。
%ld:十进制 long int类型。
%lo:八进制 long int类型。
%lx:十六进制 long int类型。
%lu: unsigned long int。
%lld:十进制 long long int类型。
%llo:八进制 long long int类型。
%llx:十六进制 long long int型。
%llu: unsigned long long int型。
%Le:科学计数法表示的long double类型浮点。
%Lf: long double类型浮点。
%n:已输出的字符串数量。该占位符本身不输出,只将值存储在指定变量之中。
%0:八进制整数。
%p:指针。
%s:字符串。
%u:符(unsigned int)。
%x:十六进制整数。
%zd: size_t类型。
%%:输出一个百分号。

9.1.4输出格式

        我们在编辑文档时,都可以设置很多的格式,printf函数也可以有输出格式。

9.1.4.1规定宽度打印

        打印时我们可以规定最小的宽度。

        %5d表示这个占位符最小的宽度为5,不够最小宽度的时候,则会在值的前面添加空格。默认是右对齐,如果要左对齐,那么则在输出内容的后面输入空格或在占位符%后添加一个-号。

9.1.4.2显示正负号

        如果想要输出的数据前显示正负号,就在占位符%后添加一个+号。

9.1.4.3规定小数位数

        当一个小数我们只希望保留两位小数,该如何做呢?只需在占位符%后添加.2就可以完成这个操作。 【在%s占位符和%添加一个.X(X为一个数)则表示要输出的长度!】规定小数位数可以和前面的规定宽度一起使用。

9.2scanf

        前面讲的都是关于输出的,接下来介绍一下用于输入的函数——scanf

9.2.1基本用法

        这个函数用来读取我们在键盘的输入,当程序运行到这段语句的时候,就会停下来,等待你敲键盘,输入好后,按下回车,scanf函数则会将你输入的值存入一个变量中。使用它时和printf函数一样,都需要引用头文件<stdio.h>,语法和printf函数很相似。

        C语言中的数据都是有类型的,所以必须要先知道输入的数据是什么类型,才能去处理数据。在这里你看到了一个前面没有讲过的运算符,就是&,在变量的前面必须要加这个运算符(指针便变量除外,如:字符串变量)原因是scanf函数传递的是地址,不是值。

        像前面的printf函数一样,scanf函数一次也能输入多个变量。

scanf("%d%d%f%f",&x,&y,&z,&m);

        上面这串代码中,格式字符串%d%d%f%f,表示输入的是整数整数浮点数浮点数。比如6         -66        3.1415        -4.0e3。这四个值依次放入x,y,z,m这四个变量中。

        scanf函数在处理数字占位符时,会自动过滤空白字符:空格,制表符,换行符等。所以我们在输入数据时,有多少个空格都不会影响到数据的输入,将数据分成几行也不会影响数据的解读。

        scanf函数处理用户输入的原理是:先将用户的输入放入缓存,等按下回车键之后,按照占位符对缓存进行解读。解读用户的输入时,会从上一次解读遗留的第一个字符开始,直到读完缓存,或者遇到第一个不符合条件的字符为止。

        我们看下面这一串代码:

#include <stdio.h>
int main()
{
    int x;
    float y;
    //输入"    -66.66e66#  0 "
    scanf("%d", &x);
    printf("%d\n", x);
    scanf("%f", &y);
    printf("%d\n", y);//两行scanf函数可以一次表示为scanf("%d%f",&x,&y);
    return 0;
}

        scanf函数开始读取,忽略数据前面的空格,从-开始读取数据,第一次读取到-66停止,因为后面的.就不属于整型的有效字符了。第二次读取时,则会从上一次停止的地方开始读取,这一从.开始读取,由于是%f,那么便会读取到.66e66(这是用科学计数法表示的浮点数)后面的#不属于浮点数的有效字符了,便会终止读取。

9.2.2scanf函数的返回值

        scanf函数其实是有返回值的,返回值为一个整数,表示成功读取的变量个数。如果没有读取到任何数据,或者匹配失败,则会返回0。如果读取任何数据之前,发生了读取错误或者是遇到了读取文件的结尾,则会返回常量EOF(-1)。

        如果输入两个数,按Ctrl+z,提前结束输入,则输出:我们看到r的值为2,表示正确读取了2个数值。

        一个数据都不输入,则显示r=-1,也就是EOF:

9.2.3占位符

        scanf函数的占位符和printf函数的占位符差距不大,这里只讲解特殊的几个

9.2.3.1  %[]

        在方括号内指定一组匹配的字符(比如%[0-9])当遇到不在集合之内字符,匹配将会停止。

9.2.3.2 %c

        其他的占位符都会自动忽略一开始的的空白字符,进行读取数据,这个字符不会忽略空白字符,总是返回当前的第一个字符,不管是不是空格。如果要强制跳过前面的空格,那么在%和c之间添加一个空格,表示跳过空格。

9.2.3.3 %s

        它的使用规则是:从当前第一个非空白的字符开始读取,直到遇到空白字符结束。

        这个规则也就说明了,%s不能读取多个字符串,除非是多个%s一起使用。

        scanf函数遇到%s占位符时,会在字符串变量的末尾放上一个空字符\0。

        scanf函数将字符度读取输入到字符数组时,不会检测字符串是否超过了数组的长度。如果存储的字符串大于数组的长度,那么会造成预想不到的结果。为了避免这个情况的出现,我们将%s写成%[m]s,m指定了读取字符串的最大长度,后面的字符就会被丢弃。

9.2.4赋值忽略符

        每个人在输入的时候都会有不同的输入方式,可能不会按预定的格式输入,则会导致scanf函数解析数据失败。我们看下面这一串代码:

        我输入的时候并没有按照预设的格式区输入,scanf函数就出现了读取错误,为了避免这种情况,scanf函数提供了赋值忽略符,(*)只要把*放在任何占位符的%后,该占位符就不会返回值,解析后将被丢弃。

        我们可以看到,%c的中间加了赋值忽略符,表示这个占位符没有对应的变量,解读后不用返回。

  • 42
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值