C语言中变量和类型的教程

126 阅读6分钟

C是一种静态类型的语言。

这意味着任何变量都有一个相关的类型,而这个类型在编译时就已经知道了。

这与你在Python、JavaScript、PHP和其他解释型语言中处理变量的方式非常不同。

当你在C语言中创建一个变量时,你必须在声明时指定一个变量的类型。

在这个例子中,我们初始化一个类型为int 的变量age

变量名可以包含任何大写或小写字母,可以包含数字和下划线字符,但不能以数字开头。AGEAge10 是有效的变量名,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为我们提供了以下类型来定义整数值。

  • char
  • int
  • short
  • long

大多数时候,你可能会使用int 来存储一个整数。但在某些情况下,你可能想选择其他3个选项中的一个。

char 类型通常用于存储ASCII图表中的字母,但它也可以用来存储小整数,从-128127 。它至少需要1个字节。

int 至少需要2个字节。 ,至少需要2个字节。 ,至少需要4个字节。short``long

正如你所看到的,我们不能保证不同的环境有相同的值。我们只有一个指示。问题是,每个数据类型中可以存储的确切数字取决于实现和架构。

我们保证short 不比int 长。而我们保证long 不比int 短。

ANSI C规范标准确定了每种类型的最小值,由于它的存在,我们至少可以知道什么是我们可以期望得到的最小值。

如果你在Arduino上进行C语言编程,不同的板子会有不同的限制。

在Arduino Uno板上,int 存储一个2字节的值,范围从-32,76832,767 。在Arduino MKR 1010上,int 存储一个4字节的值,范围从-2,147,483,6482,147,483,647 。相当大的差异。

在所有的Arduino板上,short 存储一个2字节的值,范围从-32,76832,767long 存储4字节,范围从-2,147,483,6482,147,483,647

无符号整数

对于以上所有的数据类型,我们可以在unsigned ,以0开始范围,而不是一个负数。这在很多情况下可能是有意义的。

  • unsigned char 将范围从 到至少0 255
  • unsigned int 将范围从 到至少0 65,535
  • unsigned short 将范围从 到至少0 65,535
  • unsigned long 将范围从 到至少0 4,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

以及其他看起来很奇怪的方式。

以下是一些类型。

  • float
  • double
  • long 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