C语言的数据类型

▼我是阿荣,关注我,在技术路上一起精进!▼

程序代码离不开数据处理。这篇文章将集中讲解C语言中的数据类型。

先来直观感受下:

int add(int a, int b)
{
    int result = 0; /* 创建一个有符号的整型变量result,并初始化为0 */
  
    result = a + b; /* 进行求和运算,并把结果赋值给变量result */

    return result; /* 返回result的值 */
}

在C语言中,仅有4中基本数据类型,分别是:整型、浮点型、指针和聚合类型(如数组和结构等)。在此基础上,会派生出各种各样的组合。对于一个变量而言,它包含三个属性:作用域、链接属性和存储属性

1 数据类型

变量的声明或定义的基本形式是:
数据类型 变量名;

下面将逐个数据类型进行讲解。

1.1 整型

字符(char)、短整型(short)、整型(int)和长整型(long)都称为整型数据,它们又各自分为有符号(signed)和无符号(unsigned)两种。

char a = 'a'; /* 字符型,有无符号,取决于编译器 */
unsigned char b = 'b'; /* 无符号字符型 */
short int c = 100; /* 有符号短整型 */
unsigned short int d = 100; /* 无符号短整型 */
int e = 100; /* 有符号整型 */
unsigned int f = 100; /* 无符号整型 */
long int g = 100; /* 有符号长整型 */
unsigned long int h = 100; /* 无符号长整型 */

C标准中规定了每种整型数据的最小范围,归纳为:长整型至少应该和整型一样长,而整型至少应该和短整型一样长。简单表示成long >= int >= short int

头文件limits.h中有相应的宏定义说明了各种整型数据的范围。详见下面的表格。

变量的范围

类型最小范围最小值最大值
char0~1270SCHAR_MAX
signed char-127~127SCHAR_MINSCHAR_MAX
unsigned char0~2550UCHAR_MAX
short int-32767~32767SHRT_MINSHRT_MAX
unsigned short int0~655350USHRT_MAX
int-32767~32767INT_MININT_MAX
unsigned int0~42949672950UINT_MAX
long int-2147483647~2147483647LONG_MINLONG_MAX
unsigned long int0~42949672950LONG_MAX

短整型即可表示为short,也可以表示为short int;长整型即可表示为long,也可以表示为long int。

特别的,signed关键字一般只用在char类型,而其他数据缺省情况等同于使用signed。即short、short int、signed short int等同于signed short;int、signed等同于signed int;long、long int、signed long int等同于signed long。

char具体指signed char还是unsigned char则因编译器而异。因此使用char时,最好使用其signed char与unsigned char的交集,这样便于代码的移植和复用。

1.2 浮点型

浮点数据类型包括float、double和long double。

float a = 1.1;
double b = 1.1;
long double c = 1.1;

头文件float.h中定义了float、double和long double的最大值和最小值,详见下表。

浮点数据类型的范围

类型最小值最大值
floatFLT_MINFLT_MAX
doubleDBL_MINDBL_MAX
long doubleLDBL_MAXLDBL_MAX

1.3 指针

众所周知,变量数据是存储在存储介质上的,通常是内存,拥有一个唯一的地址空间。C语言在访问变量的时候,可以通过地址进行访问,这就是指针。这种访问方式,好比说是根据每个同学的床号去找到该同学一样。

指针是C语言中的一大特点。C语言并未对指针操作做出过多的限制,用得好会出现很灵活高效的代码,用得不好,容易造成数据被错改,甚至内存溢出等问题导致系统崩溃。

指针在不指向任何地址时,建议将指针赋值为NULL,同时,在使用前,最好能判断指针是否为NULL。

指针可以指向各种数据类型变量,定义跟其他变量相似,类型后多增加一个*号。

int* a = NULL; /* 指向有符号整型数据的指针 */
float* b = NULL; /* 指向浮点型数据的指针 */

1.4 常量

常量跟变量完全一样,只是常量初始化完后不允许修改,并且使用const关键字进行修饰。如果对一个常量进行修改或重新赋值得操作,通常编译器都会发出错误提醒。

const int a = 10; /* 整型常量 */
cosnt float b = 1.1/* 浮点型常量 */

Tips:

C语言中支持一种叫做typedef的机制,它允许我们对各种数据类型定义新的名字。例如如下定义:

typedef signed int u32; /* u32等同于signed int */

2 作用域

变量被创建后,它在内存中是有存活时间的。这里涉及到一个概念叫作用域,一个变量只能存活在它的作用域里。一旦程序离开该作用域,变量就会被销毁。

标识符声明的位置决定了它的作用域。作用域分为文件作用域、函数作用域、代码块作用域和原型作用域。

Tips:
标识符就是变量、函数、数据类型等的名字。它们由大小写字母、数字和下划线组成,但不能以数字开头。

2.1 文件作用域

当一个变量在函数外进行定义时,从该文件的定义到该文件结束的代码都可以访问该变量。
test.c文件

int a = 10; /* 从该处定义开始,直到本文件结束都可以调用变量a。变量a一直存活,直到整个程序结束。*/
void fun1(void)
{
    ... /* 此处可以调用变量a */
}
void fun2(void)
{
    ... /* 此处可以调用变量a */
}

特别的,当一个文件中一个函数外定义且不带static关键字的变量(又称为全局变量),被另一个文件通过extern声明时,这个文件也可以调用该变量。

test2.c文件

extern int a; /* 通过关键字extern声明变量a */
void fun3(void)
{
    ... /* 此处可以调用test.c文件中的变量a */
}

2.2 函数作用域

函数作用域仅适用于语句标签,语句标签用于goto语句。一个函数中的所有语句标签必须唯一。

void example(void)
{
    ...
    goto EXIT_FLAG; /* 使用goto语句让程序跳转到EXIT_FLAG标签处 */
    ...
EXIT_FLAG: /* 调用goto语句后,程序从此处继续执行 */
    ...
}

2.3 代码块作用域

一对花括号之间的所有语句称为一个代码块。在代码块起始位置声明的标识符都具有代码块作用域。函数的形参也具有代码块作用域。

int example(int a) /* 形参a的作用域在最外层花括号内 */
{ /* 最外层花括号 */
    int b; /* 变量b的作用域在最外层花括号内 */
    ...
    { /* 内部花括号1 */
        int b; / 与外面的变量b是两个不同的变量,他的作用域在内部花括号1*/
        int c;
    }
    ...
    { /* 内部花括号2 */
        int c; /* 与前一个花括号内的变量c是两个不同的变量,它的作用域在内部花括号2中 */
    }
}

不推荐在嵌套代码中使用相同的变量名,虽然可以这么使用,但会造成不必要的麻烦。

2.4 原型作用域

在函数原型中声明的参数名,它的作用域只在该函数内部。

int add(int a, int b) /* 函数中声明的形参(参数名)仅在函数内部有效 */
{
    ...
}

3 链接属性

链接属性一共有3种——external(外部)、internal(内部)和none(无)
none:每个被none关键字修饰的变量或函数都是独立的个体。
internal:在同一个文件内部所有声明相同名字的变量或函数都是同一个实体。不同文件中,则是不同实体。
external:几个文件间,声明的都是同一个变量或函数都是同一个实体。

这是更深一层的知识,后面章节会深入探讨,作为初步了解,此处不做展开。

4 存储属性

变量的存储属性是指存储变量值的内存类型。它可以是普通内存、运行时堆栈、硬件寄存器。

这是更深一层的知识,后面章节会深入探讨,作为初步了解,此处不做展开。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值