C是一种静态类型的语言。
这意味着任何变量都有一个相关的类型,而这个类型在编译时就已经知道了。
这与你在Python、JavaScript、PHP和其他解释型语言中处理变量的方式非常不同。
当你在C语言中创建一个变量时,你必须在声明时指定一个变量的类型。
在这个例子中,我们初始化一个类型为int 的变量age 。
变量名可以包含任何大写或小写字母,可以包含数字和下划线字符,但不能以数字开头。AGE 和Age10 是有效的变量名,1age 则不是。
你也可以在声明时初始化一个变量,指定其初始值。
一旦你声明了一个变量,你就可以在你的程序代码中使用它,你可以在任何时候改变它的值,例如使用= 操作符,就像在age = 100; ,只要新值是相同的类型。
在这种情况下。
#include <stdio.h>
int main(void) {
int age = 0;
age = 37.2;
printf("%u", age);
}
编译器将在编译时发出警告,并将十进制数字转换为整数值。
C的内置数据类型有:int,char,short,long,float,double,long double 。让我们来了解一下这些内容。
整数
C为我们提供了以下类型来定义整数值。
charintshortlong
大多数时候,你可能会使用int 来存储一个整数。但在某些情况下,你可能想选择其他3个选项中的一个。
char 类型通常用于存储ASCII图表中的字母,但它也可以用来存储小整数,从-128 到127 。它至少需要1个字节。
int 至少需要2个字节。 ,至少需要2个字节。 ,至少需要4个字节。short``long
正如你所看到的,我们不能保证不同的环境有相同的值。我们只有一个指示。问题是,每个数据类型中可以存储的确切数字取决于实现和架构。
我们保证short 不比int 长。而我们保证long 不比int 短。
ANSI C规范标准确定了每种类型的最小值,由于它的存在,我们至少可以知道什么是我们可以期望得到的最小值。
如果你在Arduino上进行C语言编程,不同的板子会有不同的限制。
在Arduino Uno板上,int 存储一个2字节的值,范围从-32,768 到32,767 。在Arduino MKR 1010上,int 存储一个4字节的值,范围从-2,147,483,648 到2,147,483,647 。相当大的差异。
在所有的Arduino板上,short 存储一个2字节的值,范围从-32,768 到32,767 。long 存储4字节,范围从-2,147,483,648 到2,147,483,647 。
无符号整数
对于以上所有的数据类型,我们可以在unsigned ,以0开始范围,而不是一个负数。这在很多情况下可能是有意义的。
unsigned char将范围从 到至少0255unsigned int将范围从 到至少065,535unsigned short将范围从 到至少065,535unsigned long将范围从 到至少04,294,967,295
溢出的问题
考虑到所有这些限制,可能会出现一个问题:我们如何确保我们的数字不超过限制? 如果我们真的超过了限制,又会发生什么?
如果你有一个255的unsigned int ,然后你递增它,你会得到256的回报。不出所料,如果你的unsigned char 号码是255,然后你递增它,你会得到0的回报。它从最初的可能值开始重新设置。
如果你有一个255的unsigned char ,然后你向它加10,你会得到数字9 。
#include <stdio.h>
int main(void) {
unsigned char j = 255;
j = j + 10;
printf("%u", j); /* 9 */
}
如果你有一个有符号的值,其行为是未定义的。它基本上会给你一个巨大的数字,这个数字可能会有变化,就像在这种情况下。
#include <stdio.h>
int main(void) {
char j = 127;
j = j + 10;
printf("%u", j); /* 4294967177 */
}
换句话说,C语言并不能保护你不超过一个类型的极限。你需要自己来处理这个问题。
声明错误类型时的警告
当你声明变量并以错误的值初始化它时,gcc 编译器(你可能正在使用的那个)应该警告你。
#include <stdio.h>
int main(void) {
char j = 1000;
}
hello.c:4:11: warning: implicit conversion from 'int' to
'char' changes value from 1000 to -24
[-Wconstant-conversion]
char j = 1000;
~ ^~~~
1 warning generated.
而且它在直接赋值时也会警告你。
#include <stdio.h>
int main(void) {
char j;
j = 1000;
}
但如果你用例如+= 来增加数字,就不会了。
#include <stdio.h>
int main(void) {
char j = 0;
j += 1000;
}
浮点数字
浮点类型可以表示比整数大得多的数值,而且还可以表示分数,这是整数所不能做到的。
使用浮点数,我们将数字表示为十进制数字乘以10的幂。
你可能会看到浮点数被写成
1.29e-3-2.3e+5
以及其他看起来很奇怪的方式。
以下是一些类型。
floatdoublelong double
是用来表示带有小数点的数字(浮点类型)。都可以表示正数和负数。
任何C语言实现的最低要求是:float ,可以表示10^-37和10^+37之间的范围,通常使用32位实现。double ,可以表示更大的数字集合。long double ,可以容纳更多的数字。
确切的数字,和整数值一样,取决于实现方式。
在现代Mac上,一个float ,用32位表示,精度为24个有效位,8位用于编码指数。一个double ,用64位表示,精度为53个有效位,11位用于编码指数。 类型long double ,用80位表示,精度为64个有效位,15位用于编码指数。
在你的具体计算机上,你如何确定类型的具体大小?你可以写一个程序来做这件事。
#include <stdio.h>
int main(void) {
printf("char size: %lu bytes\n", sizeof(char));
printf("int size: %lu bytes\n", sizeof(int));
printf("short size: %lu bytes\n", sizeof(short));
printf("long size: %lu bytes\n", sizeof(long));
printf("float size: %lu bytes\n", sizeof(float));
printf("double size: %lu bytes\n", sizeof(double));
printf("long double size: %lu bytes\n", sizeof(long double));
}
在我的系统中,一个现代的Mac,它打印出来。
char size: 1 bytes
int size: 4 bytes
short size: 2 bytes
long size: 8 bytes
float size: 4 bytes
double size: 8 bytes
long double size: 16 bytes