网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
✨前言
- 本节对计算机语言数据表现形式详解、所谓形式,就是数据有两种表现形式:常量和变量。
- 本节对程序中基本的数据类型详解 、所谓类型,就是对数据分配存储单元的安排,包括存储单元的长度(占多少字节)以及数据的存储形式。不同的类型分配不同的长度和存储形式。
- 本节对程序中基本的数据结构详解、所谓结构,就是相互之间存在一种或者多种特定关系的数据元素集合,是带有结构的数据元素集合,它指的是数据元素之间的相互关系,即数据的组织形式。
C语言允许使用的类型如下图所示:
✨数据的表现形式
一、常量
在程序运行过程中,其值不能被改变的量称为常量。
(1)整型常量。如 12345,0,-12345 等都是整型常量。
(2)实型常量。有两种表示形式:
① 十进制小数形式,由数字和小数点组成。如123.456,0.345,-56.79,13.0 等。
② 指数形式,如12.34e3(代表12.34×10×10×10),-12.34e-3(代表-12.34×-10×-10×-10)由于在计算机输入或输出时无法表示上角或下角,故规定以字母e或E代表以10为低的指数。
但应注意:e或E之前必须有数字,且e或E后面必须为整数。如不能写成 e4,12e2.5 。
(3)字符常量。有两种形式的字符常量:
①普通字符,用但撇号括起来的一个字符,如:‘a’ , ‘Z’ , ‘2’ , ‘?’ , ‘#’ 。不能写成 ‘ab’ 或 ‘12’ 。
请注意:但撇号只是界限符,字符常量只能是一个字符,不包括但撇号。 ‘a’ 和 ‘A’ 是不同的字符常量。字符常量存储在计算机存储单元中时,并不是存储字符(如 a,z.#等)本身,而是以其代码(一般采用ASCII 代码)存储的,例如字符 ‘a’ 的ASCII 代码是97,因此,在存储单元中存放的是97(以二进制形式存放)。
②转义字符,除了以上形式的字符常量外,C语言还允许用一种特殊形式的字符常量,就是以字符 ”\“ 开头的字符序列。
常用的以 ”\“ 开头的特殊字符如下表所示。
转义字符 | 字符值 | 输出结果 |
---|---|---|
\’ | 一个单撇号( ’ ) | 输出单撇号字符 ‘ |
" | 一个双撇号( " ) | 输出双撇号字符 " |
? | 一个问号( ? ) | 输出问号字符 ? |
\ | 一个反斜线( \ ) | 输出反斜线字符 \ |
\a | 警告( alert ) | 产生声音或视觉信号 |
\b | 退格( backspace ) | 将光标当前位置后退一个字符 |
\f | 换页( form feed ) | 将光标当前位置移到下一页的开头 |
\n | 换行 | 将光标当前位置移到下一行的开头 |
\r | 回车(carriage return ) | 将光标当前位置移到本行的开头 |
\t | 水平制表符 | 将光标当前位置移到下一个Tab位置 |
\v | 垂直制表符 | 将光标当前位置移到下一个垂直制表对齐点 |
\o、\oo、\ooo 其中o代表一个八进制数字 | 与该八进制码对应的ASCII字符 | 与该八进制码对应的字符 |
\xh[h…] 其中代表一个十六进制数字 | 与该十六进制码对应的ASCII字符 | 与该十六进制码对应的字符 |
如上表所示,列表中的字符称为转义字符,意思是将“\”后面的字符转换成另外的意义。如“\n”中的“n”不代表字母n而作为“换行”符。
(4)字符串常量。如“boy” , “123” 等,用双撇号把若干个字符括起来,字符串常量是双撇号中的全部字符(但不包括双撇号本身)。注意不能错写成 'CHINA’ , ‘boy’ ,‘123’ 。单撇号内只能包含一个字符,双撇号内可以包含一个字符串。
(5)符号常量。用#define 指令,指定用一个字符名称代表一个常量。如:
#define PI3.1416 //注意行末没有分号
这种用一个符号代表一个常量的,称为符号变量。在预编译后,符号常量已全部变成字面的常量(3.1416)。
使用符号常量有以下好处
①含义清晰
②在需要改变程序中多处用到的同一常量时,能做到“一改全改”。
二、变量
变量代表一个有名字的、具有特定属性的一个存储单元。它用来存放数据,也就是存放变量的值。在程序运行期间,变量的值是可以改变的。
变量必须先定义,后使用。在定义时指定该变量的名字和类型。
一个变量应该有一个名字,以便被引用。请注意区分变量名和变量值这两个不同的概念,变量名实际上是以一个名字代表的一个存储地址。在对程序编译连接时由编译系统给每一个变量名分配对应的内存地址。从变量中取值,实际上是通过变量名找到相应的内存地址,从该存储单元中读取数据。
三、常变量
C99允许使用常变量,方法是在定义变量时,前面加一个关键字const,如:
const int a=3;
定义a为一个整型变量,指定其值为3,而且在变量存在期间其值不能改变。
常变量与常量的异同是:常变量具有变量的基本属性:有类型,占存储单元,只是不允许改变其值。可以说,常变量是有名字的不变量,而常量是没有名字的不变量。有名字就便于在程序中被引用。
四、标识符
简单地说,标识符就是一个对象的名字。
C语言规定标识符只能由字母、数字和下画线3种字符组成,且第1个字符必须为字母或下画线。下面列出的是合法的标识符,可以作为变量名:
sum ,_total 。
✨数据类型
在计算机中,数据是存放在存储单元中的,它是具体存在的。
类型就是对数据分配存储单元的安排,不同的类型分配不同的长度和存储形式。
一、基本类型
1.1、整型类型
一个字节等于8位。
一个字节是数据存储大小为-128~127,无符号的为255。
1.1.1、基本整型(int)
编译系统分配给int型数据2个字节或4个字节(由具体的C编译系统自行决定)
如果给整型变量分配2个字节,则存储单元中能存放的最大值为0111111111111111
第一位为0代表正数,后面15位为全1,此数值是(2的15次方减1),即十进制32767。最小值为1000000000000000 ,此数值是(负2的15次方),即-32768。
因此一个整型变量的范围是 -32768~32767。超过此范围,就出现数值的“溢出”,
输出的结果显然不正确。如果给整型变量分配4个字节,其能容纳的数值范围为(负2的31次方)至(2的31次方减1),即-2147483648~2147483647
代码实例
A、有符号整型未溢出
#include <stdio.h>
int main()
{
int C_int;
C_int=2147483647;
printf("C\_int=%d\n",C_int); //打印正数
C_int=-2147483648;
printf("C\_int=%d\n",C_int); //打印正数
return 0;
}
图示
B、有符号整型溢出
#include <stdio.h>
int main()
{
int C_int;
C_int=2147483648;
printf(" C\_int=%d\n",C_int); //打印正数
C_int=-2147483648;
printf(" C\_int=%d\n",C_int); //打印正数
return 0;
}
图示
C、查看有符号整型溢出字节
#include <stdio.h>
int main()
{
int C_int;
C_int=2147483648;
char \*p;
p=&C_int;
printf(" C\_int=%d\n",C_int);//打印正数
printf(" %02x %02x %02x %02x \n",p[0],p[1],p[2],p[3]); //打印字节
C_int=-2147483648;
printf(" C\_int=%d\n",C_int); //打印正数
return 0;
}
图示
1.1.2、短整型(short int)
类型名为short int或short。编译系统分配给int 4 个字节,短整型2个字节。存储方式与int 型相同。一个短整型变量的值的范围是-32768~32767。
1.1.3、长整型(long int)
类型名为long int 或 long 。编译系统分配给long 4个字节(即32位),因此long int型变量的值的范围-2147483648~2147483647 。
1.1.4、*双长整型(long long int)
类型名为long long int 或 long long ,一般分配8个字节。这是C99新增的类型,但许多C编译系统尚未实现。
C标准没有具体规定各种类型数据所占用存储单元的长度,这是由各编译系统自行决定的。
C标准只要求long型数据长度不短于int型,short型不长于int型。
即 sizeof(short)<=sizeof(int)<=sizeof(long)<=sizeof(long long)
整型变量的符号属性
以上介绍的几种类型,变量值在存储单元中都是以补码形式存储的,存储单元中的第1个二进制代表符号。整型变量的值的范围包括负数到正数。
为了充分利用变量的值的范围,可以将变量定义为“无符号”类型。可以在类型符号前面加上修饰符 unsigned ,表示指定该变量是”无符号整数“ 类型。如果加上修饰符 signed ,则是”有符号类型“。因此,在以上4种整型数据的基础上可以扩展为以下8种整型数据:
有符号基本整型 [signed] int
无符号基本整型 unsigned int
有符号短整型 [signed] short [int]
无符号短整型 unsigned short [int]
有符号长整型 [signed] long [int]
无符号长整型 unsigned long [int]
有符号双长整型* [signed] long long [int]
无符号双长整型* unsigned long long [int]
类型 | 字节数 | 取值 |
---|---|---|
int() | 4 | -2147483648 ~ 2147483647 |
unsigned int() | 4 | 0 ~ 4294967295 |
short() | 2 | -32768 ~ 32767 |
unsigned short() | 2 | 0 ~ 65535 |
long() | 4 | -2147483648 ~ 2147483647 |
unsigned long() | 4 | 0 ~ 4294967295 |
long long() | 8 | -9223372036854775808 ~ 9223372036854775807 |
unsigned long long() | 8 | 0 ~ 18446744073709551615 |
以上有”*“ 的是C99增加的,方括号表示其中的内容是可选的,即可以有,也可以没有。如果既未指定为signed 也未指定为unsigned的,默认为”有符号类型“。如signed int a 和 int a 等价。
有符号整型数据存储单元中最高位代表数值的符号(0 为正,1为负)。如果指定unsigned (为无符号)型,存储单元中全部二进位(b)都用作存放数值本身,而没有符号。无符号型变量只能存放不带符号的整数,如123,而不能存放负数,如-123。
由于左面最高位不再用来表示符号,而用来表示数值,因此无符号整型变量中可以存放的正数的范围比一般整型变量中正数的范围扩大一倍。
1.1.5、字符型(char)
由于字符是按其代码(整数)形式存储的,因此C99把字符型数据作为整数类型的一种。但是,字符型数据在使用上有自己的特点,因此把它单独列为一节来介绍。
字符与字符代码
字符与字符代码并不是任意写一个字符,程序都能识别。例如代表圆周率的Π在程序中是不能识别的,只能使用系统的字符集中的字符,目前大多数系统采用ASCII字符集。各种字符集(包括ASCII字符集)的基本集都包括了127个字符。其中包括:
字母:大写英文字母A~Z ,小写英文字母a ~ z。
数字:0~9。
专门符号:29个,包括
!“ # & ‘ () * + — , / : ; < = > ? [ \ ] ^ _ ` { | } ~
空格符:空格、水平制表符(tab) 、垂直制表符 、换行 、换页(form feed)。
不能显示的字符:空(null)字符 (以 ’\0‘表示)、警告(以’\a’表示)、退格(以’\b‘表示)、回车(以’\r’表示)等。
前已说明,字符是以整形形式(字符的ASCII代码)存放在内存单元中的。例如
大写字母’A’ 的ASCII 代码是十进制数 65 ,二进制 形式为 1000001 。
代码实例
#include <stdio.h>
int main()
{
//输出字符A的整型
printf("'A' is %d\n",'A');
//输出整型65的字符型
printf("65 is %C\n",65);
return 0;
}
图示
1.1.6、*布尔型(bool)
布尔(Boolean)以英国数学家、布尔代数的奠基人乔治布尔(George Boole)命名。
bool是在C99标准中引入的类型,bool是专门用来表示真假的类型(即:bool类型只有两种情况true或false,也就是真或者假,没有第三种情况)。在引用bool类型前需要引用头文件<stdbool.h>。
代码实例
#include <stdio.h>
#include <stdbool.h>
int main()
{
bool a;
a=10;
printf("bool is %d\n",a);
a=-1;
printf("bool is %d\n",a);
a=0;
printf("bool is %d\n",a);
return 0;
}
图示
2.1、浮点类型
2.1.1、单精度浮点型(float)
(1) float 型(单精度浮点型)。
编译系统为每一个float型变量分配 4个字节,数值以规范化的二进制数指数形式存放在存储单元中。
在存储时,系统将实型数据分成小数部分和指数部分两个部分,分别存放。小数部分的小数点前面的数为0。
2.1.2、双精度浮点型(double)
(2)double型(双精度浮点型)。
为了扩大能表示的数值范围,用8个字节存储一个double型数据,可以得到15位有效数字,为了提高运算精度,在C语言中进行浮点数的算术运算时,将float型数据都自动转换为double型,然后进行运行。
2.1.3、复数浮点型(float_complex,double_complex,long long_complex)
(3)long double(长双精度)型,不同的编译系统对 long double 型的处理方法不同,有的编译器对long double 型分配16个字节,而有的编译器则对 long double型和double型一样处理,分配8个字节。
二、枚举类型(enum)
如果一个变量只有几种可能的值,则可以定义为枚举(enumeration)类型,所谓“枚举”就是指把可能的值一 一 列举出来,变量的值只限于列举出来的值 的范围内。
声明枚举类型用enum开头。例如:
enum Weekday{sun,mon,tue,wed,thu,fri,sat};
以上声明了一个枚举类型 enum Weekday 。 然后可以用此类型来定义变量。例如:
[枚举类型]enum Weekday [枚举变量] workday , weekend ;
workday 和 weekend 被定义为枚举变量,花括号中的 sun , mon , … ,sat 称为枚举元素或枚举常量。它们是用户指定的名字。枚举变量和其他数值型量不同,
它们的值只限于花括号中指定的值之一。例如枚举变量workday 和 weekend 的值只能是 sun 到 sat 之一。
枚举常量是由程序设计者命名的,用什么名字代表什么含义,完全由程序员根据自己的需要而定,并在程序中作相应处理。
也可以不声明有名字的枚举类型,而直接定义枚举变量,例如:
enum {sun ,mon ,tue,wed,thu,fri,sat} workday ,weekend ;
声明枚举类型的一般形式为
enum [枚举名] {枚举元素列表};
其中,枚举名应遵循标识符的命名规则,上面的Weekday 就是合法的枚举名。
说明:
(1) C编译对枚举类型的枚举元素按常量处理,故称枚举常量。不要因为它们是标识符(有名字)而把它们看作变量,不能对它们赋值。
例如:
sun=0; mon=1; //错误,不能对枚举元素赋值
(2) 每一个枚举元素都代表一个整数,C语言编译按定义时的顺序默认它们的值为0,1,2,3,4,5… 。
也可以人为地指定枚举元素的数值,在定义枚举类型时显式地指定,例如:
enum Weekday {sun = 7 , mon=1,tue,wed,thu,fri,sat} workday ,week_end;
指定枚举常量sun的值为7,mon为1,以后顺序加1,sat 为 6。
2.1、实用场景
宏定义7个别名
#define MON 1
#define TUE 2
#define WED 3
#define THU 4
#define FRI 5
#define SAT 6
#define SUN 7
使用枚举实现
enum DAY
{
MON=1, TUE, WED, THU, FRI, SAT, SUN
};
代码实例
#include <stdio.h>
enum DAY
{
MON=1, TUE, WED, THU, FRI, SAT, SUN
};
int main()
{
enum DAY day;
day = MON;
printf("The %d day \n",day);
day = TUE;
printf("The %d day \n",day);
day = WED;
printf("The %d day \n",day);
day = THU;
printf("The %d day \n",day);
day = FRI;
printf("The %d day \n",day);
day = SAT;
printf("The %d day \n",day);
day = SUN;
printf("The %d day \n",day);
return 0;
}
图示
三、空类型(void)
void 类型指定没有可用的值。它通常用于以下三种情况下:
1、函数返回为空
C中有各种函数都不返回值,或者您可以说它们返回空。不返回值的函数的返回类型为空。
例如: void printf(int num);
代码实例
#include <stdio.h>
void printf\_d(int num);
int main()
{
printf\_d(1);
return 0;
}
void printf\_d(int num)
{
printf("The num is %d \n",num);
}
图示
2、函数参数为空
C中有各种函数不接收任何参数。不带参数的函数可以接收一个void。
例如 int num(void) 。
代码实例
#include <stdio.h>
int num(void);
int main()
{
int Data;
Data=num();
printf("The num is %d\n",Data);
return 0;
}
![img](https://img-blog.csdnimg.cn/img_convert/e16d518d27cef2a38e4acd4f8706ac61.png)
![img](https://img-blog.csdnimg.cn/img_convert/e59da2715088111c8e690d960ca03ddd.png)
**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
**[需要这份系统化资料的朋友,可以戳这里获取](https://bbs.csdn.net/forums/4f45ff00ff254613a03fab5e56a57acb)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
不接收任何参数。不带参数的函数可以接收一个void。
例如 int num(void) 。
**代码实例**
#include <stdio.h>
int num(void);
int main()
{
int Data;
Data=num();
printf(“The num is %d\n”,Data);
return 0;
}
[外链图片转存中…(img-LsHgiLAv-1715257600871)]
[外链图片转存中…(img-Lmj7eLJz-1715257600872)]
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!