跳过正文
  1. 文章/
  2. C/
  3. C语言基础/

3、数据类型和变量

·2888 字·6 分钟· loading · loading · ·
C C语言基础
GradyYoung
作者
GradyYoung
C语言基础 - 点击查看当前系列文章
§ 3、数据类型和变量 「 当前文章 」

数据类型
#

在 C 语言中,数据类型指的是用于声明不同类型的变量或函数的一个广泛的系统。变量的类型决定了变量存储占用的空间,以及如何解释存储的位模式。

数据类型分类
#

  • 基本类型
    • 它们是算术类型,包括两种类型:整数类型和浮点类型。
  • 枚举类型
    • 它们也是算术类型,被用来定义在程序中只能赋予其一定的离散整数值的变量。
  • void类型
    • 类型说明符 void 表明没有可用的值。
  • 派生类型
    • 它们包括:指针类型、数组类型、结构类型、共用体类型和函数类型。

基本数据类型
#

C语言中没有boolean类型,0表示假,非0整数就是真

整数类型
#

类型 存储大小 值范围
char 1 byte -128 到 127 或 0 到 255
unsigned char 1 byte 0 到 255
signed char 1 byte -128 到 127
int 2 或 4 bytes -32,768 到 32,767 或 -2,147,483,648 到 2,147,483,647
unsigned int 2 或 4 bytes 0 到 65,535 或 0 到 4,294,967,295
short 2 bytes -32,768 到 32,767
unsigned short 2 bytes 0 到 65,535
long 4 bytes -2,147,483,648 到 2,147,483,647
unsigned long 4 bytes 0 到 4,294,967,295

浮点类型
#

类型 存储大小 值范围 精度
float 4 byte 1.2E-38 到 3.4E+38 6 位小数
double 8 byte 2.3E-308 到 1.7E+308 15 位小数
long double 10 byte 3.4E-4932 到 1.1E+4932 19 位小数

void类型
#

void 类型指定没有可用的值。它通常用于以下三种情况下

  • 函数返回为空
    • C 中有各种函数都不返回值,或者您可以说它们返回空。不返回值的函数的返回类型为空。例如 void exit (int status);
  • 函数参数为空
    • C 中有各种函数不接受任何参数。不带参数的函数可以接受一个 void。例如 int rand(void);
  • 指针指向 void
    • 类型为 void * 的指针代表对象的地址,而不是类型。例如,内存分配函数 void *malloc( size_t size ); 返回指向 void 的指针,可以转换为任何数据类型。

变量
#

变量其实只不过是程序可操作的存储区的名称。C 中每个变量都有特定的类型,类型决定了变量存储的大小和布局,该范围内的值都可以存储在内存中,运算符可应用于变量上。

变量的名称可以由字母、数字和下划线字符组成。它必须以字母或下划线开头。大写字母和小写字母是不同的,因为 C 是大小写敏感的。

操作系统和C库经常使用以一个或两个下划线字符开始的标识符(如_kcab ),因此最好避免在自己的程序中使用这种名称。

定义
#

  • 语法:type variable_list;
  • type 必须是一个有效的 C 数据类型,可以是 char、w_char、int、float、double、bool 或任何用户自定义的对象。
  • variable_list 可以由一个或多个标识符名称组成,多个标识符之间用逗号分隔。
int a,b,c;
float f;

初始化
#

变量可以在声明的时候被初始化(指定一个初始值)。初始化器由一个等号,后跟一个常量表达式组成。

语法:type variable_name = value;

int a = 10,b = 20;
int be = 33; 

不带初始化的定义:带有静态存储持续时间的变量会被隐式初始化为 NULL(所有字节的值都是 0),其他所有变量的初始值是未定义的。

声明
#

变量声明向编译器保证变量以给定的类型和名称存在,这样编译器在不需要知道变量完整细节的情况下也能继续进一步的编译。变量声明只在编译时有它的意义,在程序连接时编译器需要实际的变量声明。

当您使用多个文件且只在其中一个文件中定义变量时(定义变量的文件在程序连接时是可用的),变量声明就显得非常有用。您可以使用 extern 关键字在任何地方声明一个变量。虽然您可以在程序中多次声明一个变量,但变量只能在某个文件、函数或代码块中被定义一次。

#include <stdio.h>

// 变量声明
extern int a, b;
extern int c;
extern float f;

int main ()
{
  /* 变量定义 */
  int a, b;
  int c;
  float f;
 
  /* 实际初始化 */
  a = 10;
  b = 20;
  
  c = a + b;
  printf("value of c : %d \n", c);

  f = 70.0/3.0;
  printf("value of f : %f \n", f);
 
  return 0;
}

左值和右值
#

  • C 中有两种类型的表达式:
    • 左值(lvalue):指向内存位置的表达式被称为左值(lvalue)表达式。左值可以出现在赋值号的左边或右边。
    • 右值(rvalue):术语右值(rvalue)指的是存储在内存中某些地址的数值。右值是不能对其进行赋值的表达式,也就是说,右值可以出现在赋值号的右边,但不能出现在赋值号的左边。

常量
#

  • 常量是固定值,在程序执行期间不会改变。这些固定的值,又叫做字面量。
  • 常量可以是任何的基本数据类型,比如整数常量、浮点常量、字符常量,或字符串字面值,也有枚举常量。
  • 常量就像是常规的变量,只不过常量的值在定义后不能进行修改。

整数常量
#

  • 整数常量可以是十进制、八进制或十六进制的常量,前缀指定基数:
    • 0x0X 表示十六进制
    • 0 表示八进制
    • 不带前缀则默认表示十进制

浮点常量
#

浮点常量由整数部分、小数点、小数部分和指数部分组成。您可以使用小数形式或者指数形式来表示浮点常量。

当使用小数形式表示时,必须包含小数点、指数,或同时包含两者。当使用指数形式表示时,必须包含整数部分、小数部分,或同时包含两者。带符号的指数是用 e 或 E 引入的。

字符常量
#

字符常量是括在单引号中,例如,‘x’ 可以存储在 char 类型的简单变量中。

字符常量可以是一个普通的字符(例如 ‘x’)、一个转义序列(例如 ‘\t’),或一个通用的字符(例如 ‘\u02C0’)。

在 C 中,有一些特定的字符,当它们前面有反斜杠时,它们就具有特殊的含义,被用来表示如换行符(\n)或制表符(\t)等。

转义序列 含义
\ \ 字符
' ’ 字符
" " 字符
? ? 字符
\a 警报铃声
\b 退格键
\f 换页符
\n 换行符
\r 回车
\t 水平制表符
\v 垂直制表符
\ooo 一到三位的八进制数
\xhh . . . 一个或多个数字的十六进制数

字符串常量
#

字符串字面值或常量是括在双引号 "" 中的。一个字符串包含类似于字符常量的字符:普通的字符、转义序列和通用的字符。

您可以使用空格做分隔符,把一个很长的字符串常量进行分行。

#include <stdio.h>

//三种输出结果一样
int main()
{
   char a[] = "Hello World\n";
   char b[] = "Hello \
World\n";
   char c[] = "Hello" " " "World\n";
   printf(a);
   printf(b);
   printf(c);
   return 
}

定义常量
#

在 C 中,有两种简单的定义常量的方式:

  1. 使用 #define 预处理器。
  2. 使用 const 关键字。
#include <stdio.h>

#define ABC "abc"

int main()
{
   printf(ABC);

   return 0;
}
#include <stdio.h>

int main()
{
   const char abc[] = "abc";
   printf(abc);

   return 0;
}

存储类
#

存储类定义 C 程序中变量/函数的范围(可见性)和生命周期。这些说明符放置在它们所修饰的类型之前。

  • auto
  • register
  • static
  • extern

auto 存储类
#

auto 存储类是所有局部变量默认的存储类

{
   int mount;
   auto int month;
}

上面的实例定义了两个带有相同存储类的变量,auto 只能用在函数内,即 auto 只能修饰局部变量。

register 存储类
#

register 存储类用于定义存储在寄存器中而不是 RAM 中的局部变量。这意味着变量的最大尺寸等于寄存器的大小(通常是一个字节),且不能对它应用一元的 ‘&’ 运算符(因为它没有内存位置)。

{
   register int  miles;
}

寄存器只用于需要快速访问的变量,比如计数器。还应注意的是,定义 ‘register’ 并不意味着变量将被存储在寄存器中,它意味着变量可能存储在寄存器中,这取决于硬件和实现的限制。

static 存储类
#

static 存储类指示编译器在程序的生命周期内保持局部变量的存在,而不需要在每次它进入和离开作用域时进行创建和销毁。因此,使用 static 修饰局部变量可以在函数调用之间保持局部变量的值。

static 修饰符也可以应用于全局变量。当 static 修饰全局变量时,会使变量的作用域限制在声明它的文件内。

在 C 编程中,当 static 用在类数据成员上时,会导致仅有一个该成员的副本被类的所有对象共享。

extern 存储类
#

extern 存储类用于提供一个全局变量的引用,全局变量对所有的程序文件都是可见的。当您使用 ’extern’ 时,对于无法初始化的变量,会把变量名指向一个之前定义过的存储位置。

当您有多个文件且定义了一个可以在其他文件中使用的全局变量或函数时,可以在其他文件中使用 extern 来得到已定义的变量或函数的引用。可以这么理解,extern 是用来在另一个文件中声明一个全局变量或函数。

test.c

#include <stdio.h>
 
int count = 10;

main.c

#include <stdio.h>
 
extern int count;

 
int main()
{
   printf("%d",count);

   return 0;
}
C语言基础 - 点击查看当前系列文章
§ 3、数据类型和变量 「 当前文章 」