C语言-第8章-基本数据类型


通过前面的学习,我们已经了解了C语言的基本内容,认识到程序 = 算法+数据,而C语言中数据是有类型的,这章对C语言的基本数据类型做一个较全面的介绍。

  • 数据类型
    • 基本数据类型
      • 整型 int
      • 实型(浮点型)float double
      • 字符型 char
    • 构造数据类型
      • 数组、结构、联合、枚举
    • 指针类型

8.1 整数类型

C语言支持两种根本不同的数值类型:整数类型(整型)和浮点类型(浮点型)。整数类型的值是整数,而浮点类型的值可能有小数部分。整数类型又可以从有无符号分为两大类:有符号和无符号,从其表示范围分为几类:短、中、长。之前使用的int类型属于有符号、中长度的整型。

有符号和无符号整数的区别在于表示整数的二进制位最高位(最左边的位)是否用来表示符号位,有符号整数用最高位表示数的符号,1来表示负数,0表示正数或者0(具体来说用有符号整数用补码表示数)。而无符号整数没有符号位,全部二进制位都用来表示正数或者0。因此,4个字节,共32位的无符号整数可以表示的数的范围是[0, 232-1],即[000000000000000000000000000000002,111111111111111111111111111111112]。如果是32位的有符号整数,那么由于最高位是符号位,故其表示的数的范围是[-231, 231-1]。基本上是将无符号可以表示的整数分两半,一半表示负数,一半表示正数。在有符号整数类型名称前面加上unsigned就是无符号整数类型。

用不同的字节数来存储整数造成整数的范围不同,C语言规定了从小到大3种不同长度的整数类型:short int、int、long int。每种长度的整数类型,又可以分为有符号和无符号两种类型。所以在C89中有6种整数类型。

麻烦的是,C标准并没有规定short int、int、long int具体的字节长度是多大,只是规定了:

  1. short int、int、long int中的每种类型都要覆盖一个最小取值范围。
  2. int类型的范围大于等于short int的范围,long int类型的范围大于等于int类型的范围。

这样的规定导致在不同的机器、编译环境下它们有不同的取值范围(这点比Java复杂,Java会确定整数类型的字节大小)。还好的是,在特定位数的机器下,它们的取值范围通常是相对固定的。比如,在目前比较常见的32位环境下,它们的长度和范围如下

类型名简称字节数范围-----类型名简称字节数范围
short intshort2字节/16位(有符号)-215 to 215-1 (-32, 768 to 32,767)-----unsigned short intunsigned short2字节/16位(无符号)0 to 216-1 (65535)
int4字节/32位(有符号)-231 to 231-1 ((-2147483648 to 2147483647)-----unsigned intunsigned4字节/32位(无符号)0 to 232-1 (4294967295)
long intlong4字节/32位(有符号)-231 to 231-1 ((-2147483648 to 2147483647)-----unsigned long intunsigned long4字节/32位(无符号)0 to 232-1 (4294967295)

可以看到,在这种环境下,long int和int是完全一样的。

如果在64位机器下,short和int与32位相同,分别占2字节和4字节,但是long占8字节,故有:

类型名简称字节数范围-----类型名简称字节数范围
short intshort2字节/16位(有符号)-215 to 215-1 (-32, 768 to 32,767)-----unsigned short intunsigned short2字节/16位(无符号)0 to 216-1 (65535)
int4字节/32位(有符号)-231 to 231-1 ((-2147483648 to 2147483647)-----unsigned intunsigned4字节/32位(无符号)0 to 232-1 (4294967295)
long intlong8字节/64位(有符号)-263 to 263-1 ((-9223372036854775808 to 9223372036854775807)-----unsigned long intunsigned long8字节/64位(无符号)0 to 264-1 (18446744073709551615)

值得强调的是这些表给出的范围不是C标准强制的,随着编译环境的不同而不同。确定整数类型的一种方法是检查<limits.h>头。该头是标准库的一部分,其中定义了表示每种整数类型的最大值和最小值的宏。

#include <stdio.h>
#include <limits.h>

int main()
{
  printf("The minimum value of SHORT INT = %d\n", SHRT_MIN);
  printf("The maximum value of SHORT INT = %d\n", SHRT_MAX); 
   
  printf("The minimum value of INT = %d\n", INT_MIN);
  printf("The maximum value of INT = %d\n", INT_MAX);
  
  printf("The minimum value of LONG = %ld\n", LONG_MIN);
  printf("The maximum value of LONG = %ld\n", LONG_MAX);
  
  return 0;
}

还可以使用sizeof运算符来得到各种类型占了几个字节。根据字节数也可以确定其值取值范围。其用法是

sizeof(类型名)或者sizeof(表达式)

sizeof(表达式)的含义是先计算表达式的值,然后得到存储该值的类型占几个字节。

#include <stdio.h>

int main()
{
  printf("The bytes of short int = %d\n", sizeof(short int));
   
  printf("The bytes of int = %d\n", sizeof(10));
  
  printf("The bytes of long = %d\n", sizeof(long));
  
  return 0;
}

实际上,sizeof是运算符,因此在sizeof应用于表达式时不要求加圆括号,因此我们可以用sizeof i代替sizeof(i)。但是由于sizeof运算符是一元运算符,其优先级较高,故sizeof i * f会被解释为(sizeof i) * f,可能与我们的期望不同,故建议始终加上圆括号。

8.1.1 C99中的整数类型

C99中提供了两种额外的标准整数类型:long long int和unsigned long long int。增加这两种整数类型有两个原因,一是为了满足日益增长的对超大型整数的需求,而是为了适应支持64位运算的新处理器的能力。这两个long long类型要求至少8个字节,64位宽,所以long long int类型值的范围通常为-263(-9 223 372 036 854 75 808)到263-1(9 223 372 036 854 75 807),而unsigned long long int类型值的范围通常为0到264-1(18 446 744 073 709 551 615)。

8.1.2 整数常量

在程序中以文本形式出现的数,而不是读、写或计算出来的数,称为整数常量,或者整数字面量。比如10,453。C语言除了允许用十进制书写整数常量,还支持用八进制和十六进制书写整数。

如同十进制的每个位是以10的幂为基底一样,八进制的数以8的幂为基底,而且只包含0~7,比如,八进制数237表示成十进制就是2 × 82 + 3 × 81 + 7 × 80 = 128 + 24 + 7 = 159。

十六进制的数以16的幂为基底,而且用数字0~9加上字母A~F来书写,其中A~F表示10~15之间的各个数。比如,十六进制数1AF表示成十进制就是1 × 162 + 10 × 161 + 15 × 160 = 256 + 160 + 15 = 431。

假如没有特殊的标志,很多数我们无法区别它们采用的是哪种进制,因此C语言有如下规定:

  • 十进制常量包含0~9中的数字,但是一定不能以零开头。
    如,15、345、-6574
  • 八进制常量包含0~7中的数字,而且必须以零开头。
    如,034、017、-0645
  • 十六进制常量包含0~9中的数字和A~F中的字母,而且必须以0X开头,十六进制常量中的所有字母既可以是大写,也可以是小写。如,0xff、0xfF 、0xFF、0Xff、0xfF

注意,无论是十进制、八进制还是十六进制,它们都是数的书写方式,真正存储在计算机中的是二进制。一个式子中出现多种书写形式是可以的:10 + 015 + 0x11的值等于10+13+17(十进制)。八进制和十六进制更适合于底层程序的编写,一般情况不需要使用。

十进制整数常量的类型通常为int,但如果常量的值大到无法存储在int中,就用long int类型。如果出现long int类型也无法存储,编译器用unsigned long int做尝试。确定八进制和十六进制常量的规则略有不同:编译器会依次尝试int、unsigned int、long int和unsigned long int类型,直到找到能表示该常量的类型。

有时候可以强制编译器把常量当做长整数来处理,只需在后面加一个字母L(或者l):
15L 0377L 0x4567L
为了指明常量是无符号的,可以加上字母U(或者u):
15U 456U 0xFFFFU
L和U可以结合使用,表示常量既是长整型又是无符号整型。(字母的顺序和大小写无所谓)

8.1.3 C99中的整数常量

在C99中用LL或者ll(两个字母的大小写要一致)表示long long int型。C99确定整数常量类型的规则和C89有些不同。对于没有后缀(U、u、L、l、LL、ll)的十进制常量,其类型是int、long int、long long int中能表示该值的最小类型。对于八进制和十六进制常量,可能的顺序类型为int、unsigned int、long int、unsigned long int、long long int和unsigned long long int。后面的任何后缀都会改变可能类型的列表。比如,以U(或u)结尾的常量类型一定是unsigned int、unsigned long int、unsigned long long int的一种,以L(或l)结尾的十进制常量类型一定是long int和long long int中的一种。

8.1.4 读写整数

由于整数值有八进制、十进制、十六进制这3种常用表现形式,还有有符号、无符号整数,以及短整型、长整型的区别,故读写这些类型的整数时,需要使用新的转换说明符。下表总结了各种类型和进制下的转换说明符。

printf写函数的转换说明符使用说明:

有符号十进制无符号八进制无符号十进制无符号十六进制
正常整型doux
短整型hdhohuhx
长整型ldlolulx
长长整型(C99标准)lldllollullx

短整型在正常整型转换说明符前面加上字母h;长整型在正常整型转换说明符前面加上字母l;长长整型在正常整型转换说明符前面加上字母ll(C99标准下才有长长整型)。

比如,读写短整型,

short s;

scanf("%hd", &s);
printf("%hd", s);

在C99标准中,有长长整数类型,读写这个类型的变量,在d、o、u或x前面加上字母ll:

long long ll;

scanf("%lld", &ll);
printf("%lld", ll);

可能有人会问,在输入有符号整数的时候,能否以八进制或者十六进制输入?这是可以的,只需要将%d替换为%i,输入八进制整数时,以0开头,输入十六进制时,以0x开头。

int a = 0; 
scanf("%i", &a); // 输入:017 (15的八进制 ) 
printf("%d\n", a); 
scanf("%i", &a); // 输入:0xf (15的十六进制 ) 
printf("%d\n", a); 

在这里插入图片描述
那么在输出有符号整数的时候,能否以八进制或者十六进制的形式输出整数值呢?由于C语言没有对有符号输出为八进制或者十六进制的转换说明符,故要借助于无符号整数可以输出为八进制或者十六进制,比如

int x = 20;
printf("%o", x);  // 将x看成为无符号整数来输出

输出:
在这里插入图片描述

如果要输出的是负值,需要输出其绝对值,并添加输出负号

int x = -20;
printf("-%o", -x);  // 输出负号和负数的绝对值

输出:
在这里插入图片描述

8.2 浮点类型

整数类型无法存储带小数点的数,这就需要浮点数。相比整数的范围,浮点类型的数的范围也是很大的,因此需要很大或者很小的数时也可以考虑浮点数。浮点类型由于小数点是“浮动的”得名,C语言提供了3种浮点类型:

  • float:单精度浮点数
  • double:双精度浮点数
  • long double:扩展精度浮点数

当精度要求不严格时(例如,计算带一位小数的温度),float类型是很适合的类型。double提供更高的精度,对绝大多数程序都够用了。long double支持极高精度的要求,很少会用到。
类似整数类型,C标准没有说明float、double和long double类型提供的范围和精度到底是多少,不同的计算机可以用不同方法存储浮点数。大多数现代计算机都遵循IEEE 754(即IEC 60559)的规范。
IEEE标准提供了两种主要的浮点数格式:单精度(32位)和双精度(64位)。数值以科学计数法的形式存储,每一个数都由三部分组成:符号、指数和小数。指数部分的位数说明了数值的可能大小程度,而小数部分的位数说明了精度。显然,总位数越多,指数和小数部分相应分到的位数也越多,范围也就越大,精度也越高。

类型最小正值最大值精度
float1.175 49 × 10 -383.402 82 × 10 386个数字
double2.225 07 × 10 -3081.797 69 × 10 30815个数字

在不遵循IEEE标准的计算机上,上表是无效的。事实上,在一些机器上,float可以有和double相同的数值集合,或者double可以有和long double相同的数值集合。不同于在头<limits.h>中查看整型范围的宏,在<float.h>头文件中查看浮点类型特征的宏。

8.2.1 浮点数常量

浮点常量可以有很多种书写方式。例如,下面这些常量全都是表示数57.0的有效方式:

  • 57.0
  • 57.
  • 57.0e0
  • 57E0
  • 5.7e1
  • 5.7e+1
  • .57e2
  • 570.e-1

浮点常量必须包含小数点或者指数(否则会当做整数常量):其中指数指明了对前面的数进行缩放的10的幂次。如果有指数,需要在指数前面放置字母E或者e。可选符号+或-可以出现在字母的后边,注意,这里的+或-是指数幂次的正负。可以参考科学计数法。

默认情况下, 浮点常量以双精度数的形式存储。比如,C程序中的浮点常量57.0,是以double类型存储的,如果要以float类型存储,可以在浮点常量的末尾加上F或者f,比如57.0F;为了说明浮点常量必须以long double格式存储,可以在浮点常量末尾加上字母L或者l,比如57.0L。

8.2.2 读写浮点数

读取double类型的值时,在e、f或g前放置字母l:

double d;
scanf("%lf", &d);

C99之前,用printf输出double类型的值时,不要加l,直接用e、f或g,C99允许printf函数使用%le、%lf和%lg,这样与float类型不加l形成对比,但是字母l不起作用。

读写long double类型的值时,在e、f或g前放置字母L:

long double ld;
scanf("%Lf", &ld);
printf("%Lf", ld);

8.3 数值类型小结

8.3.1 整数类型的问题

整型相比于浮点型,对数值的表示是精确的,但是问题是每一种整型变量的范围都是有限的,相比于浮点型,范围更要小很多。整数运算的时候很容易出现“溢出”现象。比如

int i = 100000 * 100000;
printf("%d\n", i);

显示结果不正确,因为正确的结果超出了int型的范围。还有

short i = 32767 + 1;
printf("%hd\n", i);

integeroverflow
结果显示为负数。这也是因为溢出问题。

整数类型有好多种,建议范围足够的话就使用int,注意不要使用无符号整型,尤其是和有符号整型混用。

8.3.2 浮点类型的问题

与整数类型相反,浮点类型的优点是表示的数值范围很大,但是精度有限。(这也很好理解,像32位机器上,int和float都用4个字节表示,那么在精度和范围之中只能二取一,无法做到兼顾,毕竟用来存储的二进制位是有限的。)

float a = 1000.43f, b = 1000.0f;
printf("%f\n", a - b);

floatroundoff1

就像1/3是无限循环小数0.3333…一样,有的数本身也就无法用固定的位数表示。比如,

printf("%.16f\n", 2.0 - 1.1);

floatroundoff2

浮点型有几种,建议日常就使用double类型,一般情况下精度足够了。

8.4 字符类型

字符类型变量用来存储字符

char ch;
ch = 'a';
ch = '0';
ch = ' ';

问题来了,字符变量ch是如何存储字母’a’、'0’以及空格的呢?还有它还可以存储其它的字符有哪些呢?在字符类型上还有哪些操作呢?

实际上,这几个问题是紧密相关的。C语言中存储字符,实际上存储的是字符在ASCII字符集下的码值,比如,字符’a’的码值为97,‘A’的码值为65,而空格字符’ '的码值为32。就像用int类型变量存储整数那样,char类型变量也是存储了这些字符的整数码值。故C语言把char类型当做小整数来处理。只是因为char类型变量只占1个字节,即8个位,故其表示的整数范围有限。在ASCII编码中,字符的取值范围是00000002~11111112,可以看成是0~127的整数,它们是可以被8位char类型变量全部存储的。

C语言把char类型当做小整数来处理。比如

char ch;
int i;
i = 'a';  // i里面存储了'a'的码值97
ch = 97; //ch里面存储了码值97,被认为存储了'a'
ch += 1; //ch里面存储了码值98,被认为存储了'b'

判断字符是否是小写字母,

if ('a' <= ch && ch <= 'z'){
  ch = ch - ('a' - 'A');  // 将ch转换为了其对应的大写字母
}

上述两块代码有意义是因为’a’~‘z’以及’A’~'Z’的码值是连续的。尽管字符类型可以当成小整数来处理,但是处理的方式还是与字符相关的,并不适合做一般意义上的算术运算,比如乘法或者除法,像'a' * 3或者'a' + ‘b’就是语法允许,但是没有意义的运算。

8.4.1 转义字符

一般情况下,字符常量是用单引号括起来的。而然有些字符是无法用上述方式书写的,有些字符无法键盘输入。因此,C语言提供了一种特殊的表示法:转义序列。
转义序列共有两种形式:字符转义序列和数字转义序列。
下表给出完整的字符转义序列

名称转义序列
警报(响铃)符\a
回退符\b
换页符\f
换行符\n
回车符\r
水平制表符\t
垂直制表符\v
反斜杠\\
问号\?
单引号\’
双引号\"

最常用的转义字符是’\n’,表示输出一个换行,接下来的输出会另起一行。如果printf输出内容中有反斜杠、单引号或者双引号,需要用反斜杠’\'对它们进行转义。

转义序列列表没有包含所有无法打印的ASCII字符,只包含了最常用的。而数字转义序列可以表示任何字符。

为了把特殊字符写成数字转义序列,首先需要在ASCII码表中查找字符的八进制或十六进制值。比如,换行符(十进制10)对应的八进制值为12,对应的十六进制值为a

  • 八进制转义序列 由字符\和跟随其后的一个最多含有三位数字的八进制数组成。比如,上述字符写成\12。注意这里与八进制整数常量不同,不要写开头的0。
  • 十六进制转义序列 由\x和跟随其后的一个十六进制数组成。上述字符写成\xa或\xA的形式。字符x必须小写,这与十六进制常量中字母大小写都可以有所不同。注意这里也与十六进制整数常量不同,不要写开头的0。

作为字符常量使用时,转义序列必须用一对单引号括起来,比如,换行符要写成’\12’或者’\xa’。转义序列可能有些隐晦,所以采用#define的方式给它们起个容易理解的名字是个不错的主意,比如:
#define ESX '\33'

8.4.2 用scanf和printf读/写字符

字符变量的读写转换说明使用%c:

char ch;
scanf("%c", &ch);
printf("%c", ch);

这里有一个容易出错的地方是所有的字符,包括空格、换行符都是字符,都可以被读取到字符变量中,这与读取数值类型是不同的,读取数值类型的时候是会自动跳过空格、换行符的。但是读取字符的时候不会。如果下一个未读字符是空格,那么例子中scanf函数将把空格读到ch中。而一般这都不是我们的本意。为了强制scanf函数在读入实际关注的字符前跳过空白字符,需要在格式串中的转换说明符%c前加上一个空格:
scanf(" %c", &ch);
scanf格式串中的空白字符意味着“跳过零个或多个空白字符”。空白字符包含空格、换行符、制表符。

因为通常情况下scanf函数不会跳过空白,所以它很容易检查到输入行的结尾:检查刚读入的字符是否为换行符。例如,下面的循环将读入并且忽略掉当前输入行中剩下的所有字符:

do{
  scanf("%c", &ch);
}while(ch != '\n');

那么下次再调用scanf函数时,将从下一行开始读入。这个方法可以忽略当前行剩余未读的字符。

8.4.3 用getchar()和putchar()读/写字符

C语言还提供了单独的两个函数专门用来读/写字符,读字符是getchar()函数,写字符是putchar()函数。
每次调用getchar()时,它会读入一个字符并将其返回。如果需要保存这个字符,需要用赋值语句将它存储到变量中:
ch = getchar();
这句话相当于
scanf("%c", &ch);
getchar()返回的是int类型,因此也可以用int变量接收返回值。
和scanf函数一样,getchar()函数也不会在读取的时候跳过空白字符。
putchar(ch)
写单个字符ch,这句话相当于
printf("%c", ch);
读/写字符时,使用getchar函数和putchar函数比scanf和printf函数效率要高一些。

8.4.4 读字符常见问题

混合使用scanf和getchar时注意scanf函数倾向于遗留下它“扫视”过但是未读取的字符(包括空格、换行符等,读取数值类型时这个现象非常常见)。假如下面的程序的输入内容与我们常规的输入一致,即输入一个整数后按下换行,那么getchar读回的就是这个换行符。或者是空格,反正就是紧跟着整数之后的第一个字符。

int i;
char c;
printf("请输入一个整数:");
scanf("%d", &i);
printf("请输入一个字符:");
c = getchar();

如果可能出现这样的问题,建议还是使用scanf读字符,并注意在读字符的格式串前加空格:scanf(" %c", &c)

8.5 类型转换

上面我们已经看了,C语言中有不同的类型,由于字符类型本质上是一种小整数类型,因此也可以把它看成是一种整数类型。因此,C语言中可以进行数值运算的“算术类型”有:

  • 整型:
    • 字符(char)
    • 有符号整数(short int、int、long int)
    • 无符号整数(unsigned short int、unsigned int、unsigned long int)
  • 浮点型(float 、double 、long double)

那么支持在一个算术表达式中出现不同的“算术类型”吗,如果支持,那么运算的时候遵循什么规则呢?
C语言支持不同的“算术类型”参与运算,但是会做一些转换。转换的原则是:

  • 会将它们转换为同一类型再进行运算。
  • 尽量保留数值信息,减少转换信息损失。

下面就从隐式转换和显式转换两种转换介绍转换规则。隐式转换指编译器自动处理不同类型的运算,不需要程序员介入,显式转换指程序中用强制类型转换运算符进行显式的转换。

8.5.1 隐式类型转换

下面的情况会发生隐式类型转换:

  • 当算术表达式或逻辑表达式中操作数的类型不同时。
  • 当赋值运算符右侧表达式的类型和左侧变量的类型不同时。
  • 当函数调用中的实参类型与其对应的形式参数不同时。
  • 当return语句中表达式的类型和函数返回值类型不同时。

由于函数还没有介绍,这里将讨论前两种情况,3、4种函数的情况本质上与第2种情况是类似的。

8.5.1.1 隐式类型转换之算术转换

执行常用算术转换的规则还可以划分为两种情况。

  • 操作数含有浮点类型的情况(任一个操作数是浮点类型)。按照下图将类型较狭小的操作数进行提升:

    floattypeconversion

  • 两个操作数的类型都不是浮点型的情况(两个操作数都是整数类型)。
    首先对两个操作数进行整数提升(将类型低于int类型的值转换为int型或者unsigned int,比如字符型,短整型)。然后按照下图对类型较狭小的类型进行提升:

inttypeconversion

有一种特殊情况,在unsigend long int类型和long int类型长度相同时,它们都会转化为unsigned long int类型。

这个规则看似合理,实际在使用中,如果提升后两个操作数一个是有符号的,一个是无符号的,那么很可能出现意想不到的问题。比如,一个操作数是int型x,值为-10,一个是unsigned int型,值为10。显然,x是小于y的,但是,如果写出x < y这样的式子,得到的结果却是假。这是因为x < y会将int型的x值转换为unsigned int再进行比较,而-10转换为unsigned int值为一个很大的整数4 294 967 296,所以x < y的结果为假,不是期望的真。由于此类陷阱的存在,所以最好避免使用无符号整数,尤其是不要把它和有符号整数混用。

8.5.1.2 隐式类型转换之赋值转换

赋值过程中的转换遵循另外的规则,就是把赋值号右边表达式的值转换为左边变量的类型。如果变量的“宽度”比表达式的值要大,那么转换不会损失信息,否则,就丢失信息,甚至得到无意义的结果。

比如,不损失信息的转换:

char c = 'a';
int i;
float f;
double d;

i = c;
f = i;
d = f;

会损失信息的转换:

int i;
i = 829.5; // i是829

如果把超过变量类型范围的值赋值给变量,结果没有意义:

char c;
c = 1000;
i = 1.0e20;
f = 1.0e100;

这些变量赋值得到了无意义的值。

浮点常量赋值给float型变量时,一个很好的方法是在浮点常量尾部加上后缀f,f = 3.14159f;,如果没有后缀,常量3.14159是double类型,将double类型赋值给float类型,编译器认为有危险,可能会发出警告信息。

8.5.2 显式类型转换

有时候,我们想要强制将一种类型的值转换为另一种类型的值参与运算,此时就可以使用强制类型转换:
[强制类型转换表达式] (类型名)表达式
其中,类型名表示的是将表达式强制类型转换的目标类型。
比如,下面的例子使用强制类型转换将float类型转换为int型,得到浮点数的小数部分:f - (int)f
比如,C语言中整数除整数,结果还是整数,如果想在整数变量之间进行浮点数相除:(float)i1/i2
C语言把(类型名)视为一元运算符。一元运算符的优先级高于二元运算符,故先对i1进行强制类型转换运算,得到float类型的值,然后再与i2进行除法运算。除法运算时,i2会被隐式转换为float类型,最终结果是两个float类型相除的结果。即相当于((float)i1)/i2
注意,如果强制类型转换的表达式是变量,强制类型转换过后变量本身是不发生改变的,只是强转会依据变量的值得到目标类型的值。所以以上两个例子中,fi1i2的值并没有改变。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值