C语言数据类型和变量(八千五字大白话)

目录

1. 数据类型介绍

2. signed 和 unsigned

3. 数据类型的取值范围

4. 变量

5. 算术操作符:+、-、*、/、%

6. 赋值操作符:= 和复合赋值

7. 单⽬操作符:++、--、+、-

8. 强制类型转换

9. scanf和printf介绍


1. 数据类型介绍

什么是数据类型呢?

在我们c语言的编程中,提供了丰富的数据类型来描述各种数据。

例如我们用整型类型来描述整数用字符类型来描述字符使用浮点类型来描述小数

所谓“类型”,就是相似的数据所拥有的共同特征,编译器只有知道了数据的类型,才知道怎么操作 数据。这次我们主要了解内置类型:

 1.1 字符型

char

(signed) char 

unsigned char 

int main()
{
    char ch='w';
    unsigned char a='p';
    return 0;
}

 1.2 整型 

//整型

int

[signed] int

unsigned int

/短整型

short  [int]

[signed] short [int]

unsigned short [int]

//⻓整型

long [int]

[signed] long [int]

unsigned long [int]

//更⻓的整型

//C99中引⼊

long long [int]

[signed] long long [int]

unsigned long long [int]

int main()
{    
    int a=0;
    short b=0;
    long c=0;
    long long a=0;
    return 0;
}

 1.3 浮点型 

float

double

long double

int main()
{
    float a=3.14;
    double b=3.1415
    ....
    return 0;
}

 1.4 布尔类型

C 语⾔原来并没有为布尔值单独设置⼀个类型,⽽是使⽤整数 0 表⽰假⾮零值表⽰真。 在 C99 中也引⼊了 布尔类型 ,是专⻔表⽰真假的 

 _Bool

 注意布尔类型必须要包括头文件<stdbool.h>

布尔类型变量的取值是:true或者false.

int main()
{
    _Bool flag = true;
    if(falg)
        printf("hello C");//将打印hello C
    return 0;
}

 1.5 各种数据类型的长度

每⼀种数据类型都有⾃⼰的⻓度,使⽤不同的数据类型,能够创建出⻓度不同的变量,变量⻓度的不 同,存储的数据范围就有所差异。 

这时,我们可以使用sizeof来计算数据类型的长度,单位为字节。

sizeof 的计算结果是 size_t 类型的,所以我们用%zd来接收。

#include<stdio.h>

int main()

{

        int a = 10;

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

        printf("%zd\n", sizeof a);//a是变量的名字,可以省略掉sizeof后边的()

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

        printf("%zd\n", sizeof(3 + 3.5));

        return 0;

}

那么每个数据类型的长度是多少呢: 

#include<stdio.h>
int main()
{
     printf("%zd\n", sizeof(char));//1
     printf("%zd\n", sizeof(_Bool));//1
     printf("%zd\n", sizeof(short));//2
     printf("%zd\n", sizeof(int));//4
     printf("%zd\n", sizeof(long));//4
     printf("%zd\n", sizeof(long long));//8
     printf("%zd\n", sizeof(float));//4
     printf("%zd\n", sizeof(double));//8
     printf("%zd\n", sizeof(long double));//8
     return 0;
}

2. signed 和 unsigned

C 语⾔使⽤ signed 和 unsigned 关键字修饰字符型整型类型的。

signed 关键字,表⽰⼀个类型带有正负号,包含负值;

unsigned 关键字,表⽰该类型不带有正负号,只能表⽰零和正整数。

对于 int 类型,默认是带有正负号的,也就是说 int 等同于 signed int 。 

signed int a;

// 等同于int a; 

int 类型也可以不带正负号,只表⽰⾮负整数。这时就必须使⽤关键字 unsigned 声明变量。 

unsigned int a; 

整数变量声明为 unsigned 的好处是,同样⻓度的内存能够表⽰的最⼤整数值,增⼤了⼀倍。

⽐如,16位的 signed short int 的取值范围是:-32768~32767,最⼤是32767;

⽽ unsigned short int 的取值范围是:0~65535,最⼤值增⼤到了65,535。

32位的 signed int 的取值范围可以参看 limits.h 中给出的定义。 

signed char c; // 范围为 -128 到 127

unsigned char c; // 范围为 0 到 255 

3. 变量

 3.1 变量的创建 

既然我们了解了数据类型之后,我们应该怎么正确的使用它呢?

数据类型是为了创造变量, 那什么是变量呢?

C语⾔中把经常变化的值称为变量,不变的值称为常量

变量创建的语法形式是这样的:

数据类型    变量名

           int     a; //整型变量

          float   b; //浮点型变量

          char   ch; //字符型变量

若我们在创造变量后,赋给它一个值,这就叫做初始化:

int a=0;

float b=0;

char ch='w';  

 3.2 全局变量与局部变量 

• 全局变量:在⼤括号外部定义的变量就是全局变量 全局变量的使⽤范围更⼴,整个⼯程中想使⽤,都是有办法使⽤的。

• 局部变量:在⼤括号内部定义的变量就是局部变量 局部变量的使⽤范围是⽐较局限,只能在⾃⼰所在的局部范围内使⽤的。 

#include<stdio.h>

int a=100; //全局变量

int main()

{

        int b=0; //局部变量

        return 0;

}

如果全局变量与局部变量的名字相同呢: 

#include<stdio.h>

int a=100; //全局变量

int main()

{

        int a=10; //局部变量

        printf("%d",a);//打印10

        return 0;

}

若全局变量与局部变量名字相同,则局部变量优先使⽤。 

全局变量和局部变量在内存中存储在哪⾥呢?

⼀般我们在学习C/C++语⾔的时候,我们会关注 内存中的三个区域:栈区、堆区、静态区

1. 局部变量是放在内存的栈区

2. 全局变量是放在内存的静态区

3. 堆区是⽤来动态内存管理的

4. 算术操作符:+、-、*、/、%

C语⾔中为了⽅便运算,提供了⼀系列操作符,其中有⼀组操作符叫:算术操作符。

分别是: + - * \ % ,这些操作符都是双⽬操作符

注:操作符也被叫做:运算符,是不同的翻译,意思是⼀样的。 

#include<stdio.h>

int main()

{

        int a=2;

        int b=3;

        c=a+b; // +的应用

        d=b-a; //  -的应用

        e=b/a; //  / 的应用

        f=b%a; // %的应用

        printf("%d",c);  //打印5

        printf("%d",d);  //打印1

        printf("%d",e);  //打印1

        printf("%d",f);   //打印1

        return 0;

}

注意:这里的除法为什么是1而不是1.5呢?取模为什么是1呢?

这是因为在计算机中除法 / 运算,3/2算的是商1,而取模%算的则是余数1

5. 赋值操作符:= 和复合赋值

在创造一个变量时, 给它赋一个值,就叫做初始化。

变量创造好之后,再给一个值,就叫做赋值。

int a=0; //初始化

a=10; //赋值,这里的“=”就是赋值操作符 

 5.1 连续赋值 

赋值操作符也可以连续赋值,如: 

int a = 3;

int b = 5;

int c = 0;

c = b = a+3;  //b=6,c=b=6

C语⾔虽然⽀持这种连续赋值,但是写出的代码不容易理解,建议还是拆开来写,这样⽅便观察代码的 执⾏细节。 

int a = 3;

int b = 5;

int c = 0;

b = a+3; //b=6

c = b;  //c=6

这样写,在调试的是,每⼀次赋值的细节都是可以很⽅便的观察的。 

 5.2 复合赋值符

在写代码时,我们经常可能对⼀个数进⾏⾃增、⾃减的操作,如下代码: 

int a = 10;

a = a+3; //a=13

a = a-2; //a=11

这样代码C语⾔给提供了更加⽅便的写法: 

int a = 10;

a += 3; //a=13

a -= 2;  //a=11

C语⾔中提供了复合赋值符,⽅便我们编写代码,这些赋值符有:

+=         -=         *=         /=         %=        

 >>=         <<=        

&=         |=         ^= 

6. 单⽬操作符:++、--、+、-

 前⾯介绍的操作符都是双⽬操作符,有2个操作数的。C语⾔中还有⼀些操作符只有⼀个操作数,被称 为单⽬操作符。 ++、--、+(正)、-(负) 就是单⽬操作符的。

 6.1 前置++和后置++

 前置++ 

//前置++

 int a = 10;

int b = ++a; //++的操作数是a,是放在a的前⾯的,就是前置++

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

如何计算呢?在上面的代码中,判断为前置++,

口诀是:先加1,再使用  ,a=a+1,b=a就能得到b=11,如下:

 int a = 10;

a = a+1;

b = a;

printf("a=%d b=%d\n",a , b); //输出的结果是:11 11

 后置++

//后置++

int a = 10;

int b = a++;//++的操作数是a,是放在a的后⾯的,就是后置++

printf("a=%d b=%d\n",a , b); //输出的结果是:11 10

如何计算呢?在上面的代码中,判断为后置++,

口诀是:先使用,再+1  ,b=a,a=a+1就能得到b=10,如下:

int a = 10;

int b = a;

a = a+1;

printf("a=%d b=%d\n",a , b); //输出的结果是:11 10

 6.2 前置--和后置--

前置-- 

如果你听懂了前置++,那前置--是同理的,只是把加1,换成了减1; 

//前置--

int a = 10;

int b = --a;//--的操作数是a,是放在a的前⾯的,就是前置--

printf("a=%d b=%d\n",a , b);//输出的结果是:9 9 

后置-- 

//后置--

int a = 10;

int b = a--;//--的操作数是a,是放在a的后⾯的,就是后置--

printf("a=%d b=%d\n",a , b);//输出的结果是:9 10 

7. 强制类型转换

在操作符中还有⼀种特殊的操作符是强制类型转换,语法形式很简单,形式如下: 

(类型) 

请看代码: 

int a = 3.14;

 // a的是int类型, 3.14是double类型,两边的类型不⼀致,编译器会报警告 

为了消除这个警告,我们可以使⽤强制类型转换: 

int a = (int)3.14;

 // 意思是将3.14强制类型转换为int类型,这种强制类型转换只取整数部分 

 // 则a=3

俗话说,强扭的⽠不甜,我们使⽤强制类型转换都是万不得已的时候使⽤,如果不需要强制类型转化 就能实现代码,这样⾃然更好的。 

8. scanf和printf介绍

 8.1 printf

  8.1.1 用法

printf() 的作⽤是将参数⽂本输出到屏幕。它名字⾥⾯的 f 代表 format (格式化),表⽰可以 定制输出⽂本的格式。

#include<stdio.h>

 int main()

{

        printf("Hello World");

         return 0;        

}

上⾯命令会在屏幕上输出⼀⾏⽂字“Hello World”。

printf() 不会在⾏尾⾃动添加换⾏符,运⾏结束后,光标就停留在输出结束的地⽅,不会⾃动换 ⾏。

为了让光标移到下⼀⾏的开头,可以在输出⽂本的结尾,添加⼀个换⾏符 \n 。 

#include<stdio.h>

 int main()

{

        printf("Hello\nWorld\n");

  // 上面打印出来的是相同的

        printf("Hello\n");

        printf("World\n");       

        return 0;        

}

printf() 是在标准库的头⽂件 stdio.h 定义的。使⽤这个函数之前,必须在源码⽂件头部引⼊这 个头⽂件。 

  8.1.2 占位符

printf() 可以在输出⽂本中指定占位符。

所谓 “占位符”,就是这个位置可以⽤其他值代⼊。

// 输出 There are 3 apples

#include<stdio.h>

int main() 

{

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

        return 0;

}  

上⾯⽰例中, There are %d apples\n 是输出⽂本,⾥⾯的 %d 就是占位符,表⽰这个位置要 ⽤其他值来替换。占位符的第⼀个字符⼀律为百分号 % ,第⼆个字符表⽰占位符的类型, %d 表⽰这 ⾥代⼊的值必须是⼀个整数

printf() 的第⼆个参数就是替换占位符的值,上⾯的例⼦是整数 3 替换 %d 。执⾏后的输出结果 就是 There are 3 apples 。 

常⽤的占位符除了 %d ,还有 %s 表⽰代⼊的是字符串。 

#include<stdio.h>

int main()

{

         printf("%s will come tonight\n", "zhangsan");

         return 0;

}  

上⾯⽰例中, %s 表⽰代⼊的是⼀个字符串,所以 printf() 的第⼆个参数就必须是字符串,这个例 ⼦是 zhangsan 。执⾏后的输出就是 zhangsan will come tonight 。 

输出⽂本⾥⾯可以使⽤多个占位符。 

#include<sdtio.h>

int main()

{

        printf("%s says it is %d o'clock\n", "lisi", 21);

        return 0;

}  

上⾯⽰例中,输出⽂本 %s says it is %d o'clock 有两个占位符,第⼀个是字符串占位 符 %s ,第⼆个是整数占位符 %d ,分别对应 printf() 的第⼆个参数( lisi )和第三个参数 ( 21 )。

执⾏后的输出就是 lisi says it is 21 o'clock 。 

printf() 参数与占位符是⼀⼀对应关系,如果有 n 个占位符, printf() 的参数就应该有 n + 1 个。如果参数个数少于对应的占位符, printf() 可能会输出内存中的任意值。 

  8.1.3 占位符列举 

printf() 的占位符有许多种类,与 C 语⾔的数据类型相对应。下⾯按照字⺟顺序,列出常⽤的占位 符,⽅便查找,具体含义在后⾯章节介绍。

• %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 :已输出的字符串数量。该占位符本⾝不输出,只将值存储在指定变量之中。

• %o :⼋进制整数。

• %p :指针。

• %s :字符串。

• %u :⽆符号整数(unsigned int)。

• %x :⼗六进制整数。

• %zd : size_t 类型。

• %% :输出⼀个百分号。 9.1.4 输出格式 printf() 可以定制占位符的输出格式。   8.1.4 输出格式 

printf() 可以定制占位符的输出格式。 

  8.1.4 输出格式

     8.1.4.1 限定宽度 

printf() 允许限定占位符的最⼩宽度。 

#include<stdio.h>

int main()

{

        printf("%5d\n", 123);  // 输出为 "   123"(_ _123)

        return 0;

}  

上⾯⽰例中, %5d 表⽰这个占位符的宽度⾄少为5位。

如果不满5位,对应的值的前⾯会添加空格。

输出的值默认是右对⻬,即输出内容前⾯会有空格;如果希望改成左对⻬,在输出内容后⾯添加空 格,可以在占位符的 % 的后⾯插⼊⼀个 - 号。 

#include<stdio.h>

int main()

{

        printf("%-5d\n", 123); // 输出为 "123   "(123_ _)

        return 0;

}  

上⾯⽰例中,输出内容 123 的后⾯添加了空格。 

对于⼩数,这个限定符会限制所有数字的最⼩显⽰宽度。 

// 输出 " 123.450000"

#include<sdtio.h>

int main()

{

        printf("%12f\n", 123.45);

        return 0;

}  

上⾯⽰例中, %12f 表⽰输出的浮点数最少要占据12位。由于⼩数的默认显⽰精度是⼩数点后6位, 所以 123.45 输出结果的头部会添加2个空格。 

   8.1.4.2 总是显⽰正负号

默认情况下, printf() 不对正数显⽰ + 号,只对负数显⽰ - 号。如果想让正数也输出 + 号,可 以在占位符的 % 后⾯加⼀个 + 。 

#include<sdtio.h>

int main()

{

        printf("%+d\n", 12); // 输出 +12

        printf("%+d\n", -12); // 输出 -12

        return 0;

}  

上⾯⽰例中, %+d 可以确保输出的数值,总是带有正负号。 

  8.1.4.3 限定⼩数位数

 输出⼩数时,有时希望限定⼩数的位数。举例来说,希望⼩数点后⾯只保留两位,占位符可以写 成 %.2f 。

// 输出 Number is 0.50

#include<sdtio.h>

int main()

{

        printf("Number is %.2f\n", 0.5);

        return 0;

}  

上⾯⽰例中,如果希望⼩数点后⾯输出3位( 0.500 ),占位符就要写成 %.3f 。 

这种写法可以与限定宽度占位符,结合使⽤。 

// 输出为 " 0.50"

#include<stdio.h>

int main()

{

        printf("%6.2f\n", 0.5);

        return 0;

}  

同理,在字符串中也有类似的应用: 

// 输出 hello

#include<sdtio.h>

int main()

{

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

        return 0;

}  

上⾯⽰例中,占位符 %.5s 表⽰只输出字符串“hello world”的前5个字符,即“hello”。 

 8.2 scanf 

当我们有了变量,我们需要给变量输⼊值就可以使⽤ scanf 函数,如果需要将变量的值输出在屏幕上 的时候可以使⽤ printf 函数,下⾯看⼀个例⼦: 

#include<sdtio.h>

int main()

{

        int score = 0;

        printf("请输⼊成绩:");  

        scanf("%d", &score);

        printf("成绩是:%d\n", score);

        return 0;

}

运⾏截图: 

 

   8.2.1 基本⽤法

scanf() 函数⽤于读取⽤⼾的键盘输⼊。

程序运⾏到这个语句时,会停下来,等待⽤⼾从键盘输⼊。

⽤⼾输⼊数据、按下回⻋键后, scanf() 就会处理⽤⼾的输⼊,将其存⼊变量。

它的原型定义在头⽂件 stdio.h 。 scanf() 的语法跟 printf() 类似。 

int a=0;

scanf("%d",&a);

注意:变量前⾯必须加上 & 运算符(指针变量除外),因为 scanf() 传递的不是值,⽽是地址, 即将变量 i 的地址指向⽤⼾输⼊的值。

如果这⾥的变量是指针变量(⽐如字符串变量),那就不⽤加 & 运算符。 

 scanf() 处理数值占位符时,会⾃动过滤空⽩字符,包括空格、制表符、换⾏符等。

scanf() 处理⽤⼾输⼊的原理是,⽤⼾的输⼊先放⼊缓存,等到按下回⻋键后,按照占位符对缓存 进⾏解读。 

   8.2.2 占位符

 scanf() 常⽤的占位符如下,与 printf() 的占位符基本⼀致。

• %c :字符。

• %d :整数。

• %f : float 类型浮点数。

• %lf : double 类型浮点数。

• %Lf : long double 类型浮点数。

•  %s :字符串。 

上⾯所有占位符之中,除了 %c 以外,都会⾃动忽略起⾸的空⽩字符。

scanf("%s","abc  d"); // 输入成功的只有abc

scanf("%d", &a); // 若输入12  3,输入成功的只有12

%c 不忽略空⽩字符,总是返 回当前第⼀个字符,⽆论该字符是否为空格。

如果要强制跳过字符前的空⽩字符,可以写成 scanf(" %c", &ch) ,即 %c 前加上⼀个空格,表 ⽰跳过零个或多个空⽩字符。

下⾯要特别说⼀下占位符 %s ,它其实不能简单地等同于字符串。

它的规则是,从当前第⼀个⾮空⽩字符开始读起,直到遇到空⽩字符(即空格、换⾏符、制表符等)为⽌。 

   8.3 小提示(C4996和C6031)

若使用Vs编程,难免会遇到以下情况:

这是因为在VS中认为scanf函数是一个不大安全的函数, 那我们应该怎么处理呢?

只要在开头加上这两句话,这个问题就可以解决了 

评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值