目录

1. 基本类型和构造类型

1.1 基本类型

1.2 构造类型

2. C语言两大类型(存储格式根本上不同)

3. 整数类型

3.1 6种有效组合

3.2 整数常量

3.3 整数溢出

3.4 读写整数

4. 浮点类型

4.1 3种浮点类型

4.2 浮点常量

4.3 读写浮点数

5. 字符类型

5.1 字符类型要点

5.2 字符类型的符号

5.3 算术类型

5.4 转义序列

5.5 字符处理函数

5.6 用scanf和printf读写字符

5.7 用getchar和putchar读写字符

6. 类型转换

6.1 算术运算的硬件限制

6.2 隐式转换的时机

6.3 常用算术转换

6.4 赋值过程中的转换

6.5 强制类型转换

7. 类型定义typedef

8. sizeof运算符


1. 基本类型和构造类型

1.1 基本类型

基本类型包含整数类型、浮点类型、字符类型等,其存储特点是每个变量单独存放,亦称简单变量

char x = 'a';
int x1 = 0;
int x2 = 2 * x1;

各变量之间独立存放,无任何联系

1.2 构造类型

由基本类型构造而成,如数组、结构体、联合体、枚举类型

构造类型的特点,

① 构造类型的每一个分量是一个变量,他可以是一个简单类型或者构造类型。即构造类型的分量也可以是一个构造类型(比如二维数组和结构体数组)

② 构造类型分量的使用方法与简单变量相同

③ 构造类型的分量占用相邻的存储空间(注意:由于对齐问题,结构体成员间可能会有空隙)

④ 对于构造类型的变量来说,重点是访问其分量的方法

2. C语言两大类型(存储格式根本上不同)

① 整数类型(含字符型):补码存储

a. 有符号整型(默认情况)

b. 无符号整型(需用unsigned声明,一般用于系统底层编程)

② 浮点类型:介码存储

3. 整数类型

3.1 6种有效组合

[ ]中内容可省略

short [int]
unsigned shor [int]
int
unsigned int
long [int]
unsigned long [int]

说明1:6种类型表示范围随机器不同(由实现定义),但有2条原则,

① C标准要求每种类型都要覆盖一个确定的最小取值范围

②空间大小,long int >= int >= short,具体范围见<limits.h>头文件

由于不同的编译器或者运行平台上相同的整数类型被分配的内存空间可能不相同,进而可能导致程序中行为的不一致。此时,我们可以使用<stdint.h>中定义的扩展整数类型,这些扩展整数类型固定了自己所占用的内存空间,他可以保证在所有平台上,这个变量所占用的内存字节数一致

说明2:C99新增long long int和unsigned long long int

说明3:整数类型在编程中的2个注意点

① 溢出问题(int + int ==> 2100000000 + 210000000,结果无法用int 表示)

② 常用算术转换问题,尤其是有符号/无符号整型混合计算问题(unsigned + signed)

3.2 整数常量

整数常量即在程序中以文本形式出现的数值,他们的3种进制及存储类型如下,

① 十进制(一定不能以0开头)

int --> long int --> unsigned long int(原则:尽量保证有符号)

② 八进制(必须以0开头)

int --> unsigned int --> long int --> unsiged long int

③ 十六进制(总以0x/0X开头,数中字母大小写均可)

存储类型与八进制相同

说明1:八进制和十六进制只是书写数的方式,他们不会影响数的实际存储

说明2:八进制和十六进制适合底层编程

说明3:可以强制编译器把常量作为长整数或无符号数,15l,15L,15u,15U,15lu

3.3 整数溢出

有符号数:未定义行为

无符号数:对2^n取模(n为存储位数),也就是发生绕回

说明:当int变量溢出时,我们的第一反应是把类型由int换为long int。但我们还必须检查数据类型改变对程序其他部分的影响,比如读写转换说明应由%d改为%ld

3.4 读写整数

① 读写无符号整数

%u:十进制

%o:八进制

%x:十六进制

② 读写短整型时,在d、u、o或x前加h

③ 读写长整型时,在d、u、o或x前加l

4. 浮点类型

4.1 3种浮点类型

float / double / long double

差别:① 范围;② 精度

浮点数存储的3个部分:

其中指数代表数值的可能大小程度,小数则说明了精度

补充:C99中,浮点类型分为实浮点类型和复数类型

4.2 浮点常量

① 浮点常量必须包含小数点或指数

② 默认存储类型为double

如需指定为float,则加f或F(57.0f)

如需指定为long double,则加l或L(57.0l)

4.3 读写浮点数

① 读写float

%e、%f、%g

② 读写double

读时一定要用%lf,%le、%lg

写时用%f(C99允许在printf中用%le、%lf 和%lg,只不过其中的l 不起作用)

③ 读写long double

在e、f 或g 之前加L(注意,是大写哦~~)

说明1:浮点型数据的舍入误差

若数据超过有效位,则被舍去,故可能产生误差。示例如下,

int main()
{float a, b;a = 123456.789e5; //数据超过有效位b = a + 20;printf(“a=%f, b=%f\n”, a, b);return 0;
}
// 输出为
// a = 12345678848.000000
// b = 12345678848.000000 (实际上发生了大数吃小数)

说明2:printf输出inf表示超出范围的浮点数(±∞),printf输出nan表示不存在的浮点数

注意:VS2012是编译不过的,上例仅作为补充

5. 字符类型

5.1 字符类型要点

① C语言把字符变量当作小整数进行处理 ---> 字符类型可以参与各种运算

② 字符常量实际上是int型而不是char型

5.2 字符类型的符号

C语言标准没有说明普通char类型数据是有符号还是无符号

可移植性技巧:不要假设char类型默认为signed或unsigned。如果有区别,用signed或unsigned来修饰char

5.3 算术类型

算术类型分为如下2类,

① 整值类型

字符类型(char)

有符号整型(signed char、short int、int、long int)

无符号整型(unsigned char、unsigned shor、unsigned int、unsigned long)

枚举类型

② 浮点类型(float、double、long double)

5.4 转义序列

① 字符转义序列(e.g. \n)

② 数字转义序列

a. 八进制转义序列:最多3位数字(因为八进制中一位表示二进制中三位),不一定以0开头(e.g. \33 \033)

b. 十六进制转义序列:最多2位数字,必须以x开头(x必须小写),但十六进制数字不限大小写(e.g. \x1b   \x1B)

说明1:由于转义序列较为隐晦,可以定义成宏

#define  ESC  '\33'

说明2:转义序列实际上被作为一个字符来对待,但如果反斜杠之后的字符和他不构成转义序列,则'\' 不起转义作用将被忽略。示例如下,

此处'\A'不是有效的转义序列,输出时忽略了'\'的作用

5.5 字符处理函数

如toupper函数,需包含<ctype.h>

5.6 用scanf和printf读写字符

① 均用%c 转换说明

② 用scanf + %c 读入字符前,不会跳过空白字符。所以可以用" %c"(空格+%c)来匹配非空白字符前的任意数量空白字符

关于scanf格式字符串中空白字符的处理,可以参考如下笔记,

http://note.youdao.com/noteshare?id=2301a8e2fc4d18b4b700e5eb8a197c3a&sub=8A0E98B031404014AB9CA46F00EEE995

5.7 用getchar和putchar读写字符

① getchar函数特性

a. 返回值为int类型

b. 不会跳过空白字符

② 惯用法

while (getchar() != '\n')  //skip rest of line;
while ((ch = getchar()) == ' ')  //skip blanks,跳过不定数量的空格字符;

③ 陷阱:数字与字符的混合输入

根源:读取字符时不跳过空白字符

示例:输入为:123空格空格c,在读入数字后,读到的第一个字符是空格

6. 类型转换

6.1 算术运算的硬件限制

在执行算术运算时,计算机比C语言限制更多,通常要求,

① 操作数有相同的大小,即存储的位数要相同

② 存储方式要相同(注意整型数和浮点数在存储方式上有根本不同)

这些硬件限制就引出了运算时的类型转换问题

6.2 隐式转换的时机

由于C语言允许表达式中混合使用基本类型,但是硬件限制不支持混合运算,因此实现方式就是通过隐式转换(implicit conversion,由编译器完成,无需程序员介入)

注意:隐式转换是C程序出错的一大原因!!!

隐式转换有如下时机,

① 当算术表达式或逻辑表达式中操作数类型不同时(常用算术转换)

② 当赋值运算符右侧表达式的类型与左侧变量的类型不匹配时(赋值过程中的转换)

③ 当函数调用中的实际参数类型与其对应的形参类型不匹配时(函数章节解释)

剧透一下,函数调用时类型转换根据调用前有无遇到函数声明行为不同,具体可参考如下笔记,

http://note.youdao.com/noteshare?id=cfd5b7d4ccabb70b5f07c7882512d0d5&sub=782B06F3206F4431B638F3749A4FB7D1

④ 当return语句中表达式的类型和函数返回值的类型不匹配时

6.3 常用算术转换

策略:把操作数转换成可以安全地适用于两个数值的“最狭小的”数据类型("安全 + 性能"策略)

整值提升(integral promotion):把字符或短整型转换成int类型(某些情况下,无符号短整型要转换unsigned int类型)

这个"某些情况"就是短整型和int型长度相同的情况(比如在16 位机上二者均为16位),此时无符号短整型的最大值(65535)超过int型最大值(32767)

下面根据2种情况讨论常用算术转换的顺序,

① 任一操作数的类型是浮点类型的情况

② 两个操作数的类型都不是浮点型的情况

陷阱:当把有符号数和无符号数混合使用时,会把有符号数转换成无符号数,此时可能会导致隐藏的编程错误

示例:int型变量i 的值为-10,unsigned int型变量u 的值为10,表达式 i < u 的值为0。因为i 转换为unsigned int型时,是一个巨大的值

特殊情况:在long int类型和unsigned int类型长度相同时(比如均为32位), 如果一个操作数是long int,一个是unsigned int,那么2个操作数均转换成unsigned long int

6.4 赋值过程中的转换

规则:把赋值运算符右边的表达式转换成左边变量的类型

注意:把某种类型的值赋给类型更狭小的变量时,如果该值在变量类型范围之外,将会得到无意义的结果

6.5 强制类型转换

// 强制类型转换表达式
(类型名) 表达式// 示例
(float)divider / divisor// (类型名)视为一元运算符,优先级高于二元运算符

说明1:有时需要使用强制类型转换来避免溢出

long i;
int j = 1000;
i = j * j;

i 为long型,应该能放下1000 * 1000的结果,问题是2个int型值相乘的结果也是int型,但j * j的结果太大,以致在某些机器上无法表示成int型

// 改进方法
i = (long)j * j;

注意:i = (long)(j * j);是不行的,因为溢出在强制类型转换之前就已经发生

说明2:思考一个计算float类型值小数部分的方法

float f;
float frac_part;frac_part = f - (int)f;

该语句有几次类型转换? 2次!

① 强制类型转换以丢掉小数

②为与f 计算,将(int)f 的值隐式转换成float类型(常用算术转换)

7. 类型定义typedef

typedef int Bool;

说明1:与宏定义实现比较

#define BOOL int

① typedef功能更强大,特别是数组和指针类型不能定义为宏

经典问题,

#define PTR_TO_INT int *
PTR_TO_INT p, q, r; // 只有p被定义

说明2:typedef是编写可移植程序的一种重要工具

typedef int Quantity;
typedef long Quangtity;

这样可以根据不同的平台来选择,但是要注意修改类型定义后相应的printf 和scanf 的转换说明也要修改

8. sizeof运算符

// sizeof可以作用于类型名、常量、变量和表达式,但sizeof运算符仅关心他们的类型
sizeof(类型名)

特别注意:sizeof表达式的值的类型是size_t,这种类型由实现定义,但一定是无符号类型。在C89中最好在显示前把表达式的值转换为一种已知类型,比如,

//选择unsigned long,是因为她是C89中最大的无符号类型
printf("size of int :%lu\n", (unsigned long)sizeof(int));

注意:sizeof是静态运算符,其结果在编译时就已决定,所以不要在sizeof 的括号中做运算,这些运算实际不会进行

C程序设计语言现代方法07:基本类型相关推荐

  1. C程序设计语言现代方法05:选择语句

    目录 1. C语言语句分类 2. 逻辑表达式 2.1 == 与 = 2.2 &&和||的短路特性 2.3 不要将==用于浮点数判断 3. if语句 4. 条件表达式 5. switch ...

  2. C程序设计语言现代方法18:声明

    目录 1. 声明的语法 2. 变量的性质 2.1 变量性质的构成 2.2 变量默认性质 2.3 修改变量默认性质 2.3.1 修改局部变量默认性质 2.3.2 修改全局变量默认性质 2.4 exter ...

  3. C程序设计语言现代方法17:指针的高级应用

    目录 1. 动态存储分配 1.1 malloc函数 1.2 calloc函数 1.3 realloc函数 1.4 free函数 2. 空指针NULL解析 2.1 NULL的定义形式 2.2 程序如何知 ...

  4. C程序设计语言现代方法15:编写大型程序

    目录 1. C语言程序一般构成 2. 源文件 2.1 源文件内容 2.2 将文件划分成多个源文件的优点 3. 头文件 3.1 包含头文件的3种方式 3.2 头文件共享内容 3.2.1 宏定义和类型定义 ...

  5. C程序设计语言现代方法14:预处理器

    目录 1. 预处理器工作原理 1.1 预处理器性质 1.2 预处理器主要功能 1.3 GCC编译过程及常用选项 1.3.1 GCC编译过程 1.3.2 编译选项实例 1.4 注意事项 2. 预处理指令 ...

  6. C程序设计语言现代方法13:字符串

    目录 1. 字符串字面量 1.1 定义 1.2 字符串字面量包含转义序列 1.3 延续字符串字面量 1.3.1 使用续行符 1.3.2 仅用空白字符分割字符串字面量 1.4 存储字符串字面量 1.5 ...

  7. C程序设计语言现代方法12:指针和数组

    目录 1. 指针的算术运算 1.1 概述 1.2 C语言支持的算术运算类型 2. 指针的比较 3. 指针用于数组处理 4. 数组名与指针 4.1 用数组名作指针 4.2 数组取下标操作 4.3 惯用法 ...

  8. C程序设计语言现代方法08:数组

    目录 1. C语言中的变量 2. 一维数组 2.1 数组的声明 2.2 数组初始化 2.3 对数组使用sizeof运算符 3. 多维数组 4. 常量数组 4. C语言数组类型 4.1 数组类型 4.2 ...

  9. C程序设计语言现代方法03:格式化输入输出

    目录 1. printf函数 1.1 基本格式 1.2 格式字符串详解 1.2.1 普通字符 1.2.2 转换说明(conversion specification) 1.3 使用注意事项 2. sc ...

最新文章

  1. 如何估算文章阅读时长?
  2. 关于Expdp/Impdp 并行导入导出详细测试结果和并行参数的正确理解!!
  3. 使用SAP WebIDE消费API Portal里创建的API时的错误消息
  4. 介绍一个非常实用的Visual Studio Code扩展 - indent-rainbow
  5. LaTeX常见文件类型
  6. 点餐系统ip地址_spring boot实战——微信点餐系统03:微信授权(用户授权),免费内网穿透(固定ip)...
  7. java中jsp时间插件_日期插件 - WEB源码|JSP源码/Java|源代码 - 源码中国
  8. 软件推荐,强力卸载软件geek uninstaller
  9. QT调用WIN32 API代码,遇到无法解析
  10. w10系统 计算机快捷键大全,Win10电脑快捷键汇总_Win10系统快捷键大全_玩游戏网...
  11. 叔叔不约---匿名聊天网 聊天图片爬虫抓取
  12. 连续8年 远见领跑|山石网科入选Gartner 2021网络防火墙魔力象限
  13. P2006 赵神牛的游戏
  14. ios 13 全局修改 present 卡片式
  15. form的onsubmit验证
  16. OpenDRIVE文件格式详解
  17. 眼睛好看是一种什么样的体验?
  18. L39.linux命令每日一练 -- 第六章 文件备份与压缩命令 -- scp和rsync
  19. Ex6_机器学习_吴恩达课程作业(Python):SVM支持向量机(Support Vector Machines)
  20. 【高等数学笔记】两类曲线积分、曲面积分的转化

热门文章

  1. c语言缩写一个人的名字,用C语言输入一个人的英文名字统计个数输出
  2. python图片矫正后对比_python库skimage 对图像进行gamma校正和log校正
  3. 2019计算机科学与技术考研分数线,2019考研中国科学技术大学复试分数线已公布...
  4. #6281. 数列分块入门 5
  5. linux用shell写正则表达式,Linux命令行与Shell脚本编程大全-shell正则表达式
  6. php curlopen,php自动提交表单的方法(基于fsockopen与curl)
  7. java 账户和密码 3次_模拟登录,给三次机会,并提示还有几次。Java实现
  8. 用控制台怎么编译java程序_怎么在cmd中运行java控制台程序?
  9. 华南理工大学计算机科学与工程学院篡改,华南理工大学涉嫌篡改成绩人员已被停职调查...
  10. java抠图边框颜色处理_java 实现抠图(项目应用场景:抠图章)