整数类型
整数类型简称整型,也就是所谓的整数。int类型通常都是32位。但是有的程序需要的int很大,无法以int类型存储,所以C语言还提供了长整型,当然如果你需要一些小的空间存储,可以用短整型。
有符号整数如果为正数或零,那么最左边的位(符号位)为0;如果是负数,则符号位为1.
不带符号位的整数的整数称为无符号整数。
常量
常量是固定值,在程序执行期间不会改变。这些固定的值,又叫做字面量。
常量可以是任何的基本数据类型,比如整数常量、浮点常量、字符常量,或字符串字面值,也有枚举常量。
常量就像是常规的变量,只不过常量的值在定义后不能进行修改。
整数常量:
整数常量可以是十进制、八进制或十六进制的常量。前缀指定基数:0x 或 0X 表示十六进制,0 表示八进制,不带前缀则默认表示十进制。
整数常量也可以带一个后缀,后缀是 U 和 L 的组合,U 表示无符号整数(unsigned),L 表示长整数(long)。后缀可以是大写,也可以是小写,U 和 L 的顺序任意。
下面列举几个常量的实例:
212 /* 合法的 */
215u /* 合法的 */
0xFeeL /* 合法的 */
078 /* 非法的:8 不是八进制的数字 */
032UU /* 非法的:不能重复后缀 */
85 /* 十进制 */
0213 /* 八进制 */
0x4b /* 十六进制 */
30 /* 整数 */
30u /* 无符号整数 */
30l /* 长整数 */
30ul /* 无符号长整数 */
浮点常量:
浮点常量由整数部分、小数点、小数部分和指数部分组成。您可以使用小数形式或者指数形式来表示浮点常量。
当使用小数形式表示时,必须包含整数部分、小数部分,或同时包含两者。当使用指数形式表示时, 必须包含小数点、指数,或同时包含两者。带符号的指数是用 e 或 E 引入的。
下面列举几个浮点常量的实例:
3.14159 /* 合法的 */
314159E-5L /* 合法的 */
510E /* 非法的:不完整的指数 */
210f /* 非法的:没有小数或指数 */
.e55 /* 非法的:缺少整数或分数 */
字符常量:
字符常量是括在单引号中,例如,'x' 可以存储在 char 类型的简单变量中。
字符常量可以是一个普通的字符(例如 'x')、一个转义序列(例如 't'),或一个通用的字符(例如 'u02C0')。
在 C 中,有一些特定的字符,当它们前面有反斜杠时,它们就具有特殊的含义,被用来表示如换行符(n)或制表符(t)等。下表列出了一些这样的转义序列码:
#include <stdio.h>
int main()
{
printf("HellotWorldnn");
return 0;
}
Hello World
字符串常量:
字符串字面值或常量是括在双引号 "" 中的。一个字符串包含类似于字符常量的字符:普通的字符、转义序列和通用的字符。
您可以使用空格做分隔符,把一个很长的字符串常量进行分行。
下面的实例显示了一些字符串常量。下面这三种形式所显示的字符串是相同的。
"hello, dear"
"hello,
dear"
"hello, " "d" "ear"
定义常量:
- 使用 #define 预处理器。
- 使用 const 关键字。
#define 预处理器
#define identifier value
具体实例:
#include <stdio.h>
#define LENGTH 10
#define WIDTH 5
#define NEWLINE 'n'
int main()
{
int area;
area = LENGTH * WIDTH;
printf("value of area : %d", area);
printf("%c", NEWLINE);
return 0;
}
value of area : 50
const 关键字
const type variable = value;
具体实例:
#include <stdio.h>
int main()
{
const int LENGTH = 10;
const int WIDTH = 5;
const char NEWLINE = 'n';
int area;
area = LENGTH * WIDTH;
printf("value of area : %d", area);
printf("%c", NEWLINE);
return 0;
}
value of area : 50
浮点类型
C语言提供三种浮点类型
- float:单精度浮点数
- double:双精度浮点数
- long double:扩展精度浮点数
当精度要求不严格时,比如计算一位小数的温度,用float。double提供更高的精度,并且满足绝大数的程序。long double支持极高的精度要求,很少用到。
字符类型
char 称为字符类型,只能用单引号' '
来包围,不能用双引号" "
包围。而字符串只能用双引号" "
包围,不能用单引号' '
包围。
#include <stdio.h>
#include <stdlib.h>
int main()
{
char a = 'E';
char b = 70;
int c = 71;
int d = 'H';
printf("a=%c, a=%dn", a, a);
printf("b=%c, b=%dn", b, b);
printf("c=%c, c=%dn", c, c);
printf("d=%c, d=%dn", d, d);
system("pause");
return 0;
}
a=E, a=69
b=F, b=70
c=G, c=71
d=H, d=72
在ASCII码表中,E、F、G、H 的值分别是 69、70、71、72。
字符和整数没有本质的区别。可以给 char 变量一个字符,也可以给它一个整数;反过来,可以给 int 变量一个整数,也可以给它一个字符。
char 变量在内存中存储的是字符对应的 ASCII 码值。如果以 %c 输出,会根据 ASCII 码表转换成对应的字符;如果以 %d 输出,那么还是整数。
int 变量在内存中存储的是整数本身,当以 %c 输出时,也会根据 ASCII 码表转换成对应的字符。
转义序列
C语言中的转义序列是在字符串文字或字符中使用时不表示自身的字符序列。 它由两个或多个以反斜杠开头的字符组成。 例如:n表示新行或换行//
类型转换
类型转换就是将数据(变量、数值、表达式的结果等)从一种类型转换为另一种类型。
将一种类型的数据赋值给另外一种类型的变量时就会发生自动类型转换,例如:
float f = 100;
int n = f;
100 是 int 类型的数据,需要先转换为 float 类型才能赋值给变量 f。
f 是 float 类型的数据,需要先转换为 int 类型才能赋值给变量 n。
在赋值运算中,赋值号两边的数据类型不同时,需要把右边表达式的类型转换为左边变量的类型,这可能会导致数据失真,或者精度降低;所以说,自动类型转换并不一定是安全的。
在不同类型的混合运算中,编译器也会自动地转换数据类型,将参与运算的所有数据先转换为同一种类型,然后再进行计算。转换的规则如下:
- 转换按数据长度增加的方向进行,以保证数值不失真,或者精度不降低。例如,int 和 long 参与运算时,先把 int 类型的数据转成 long 类型后再进行运算。
- 所有的浮点运算都是以双精度进行的,即使运算中只有 float 类型,也要先转换为 double 类型,才能进行运算。
- char 和 short 参与运算时,必须先转换成 int 类型。
注意:unsigned 也即 unsigned int,此时可以省略 int,只写 unsigned。
#include<stdio.h>
int main(){
float PI = 3.14159;
int s1, r = 5;
double s2;
s1 = r * r * PI;
s2 = r * r * PI;
printf("s1=%d, s2=%fn", s1, s2);
return 0;
}
s1=78, s2=78.539749
在计算表达式r * r * PI
时,r 和 PI 都被转换成 double 类型,表达式的结果也是 double 类型。但由于 s1 为整型,所以赋值运算的结果仍为整型,舍去了小数部分,导致数据失真。
强制类型转换是程序员明确提出的、需要通过特定格式的代码来指明的一种类型转换。换句话说,自动类型转换不需要程序员干预,强制类型转换必须有程序员干预。
强制类型转换的格式为:
(type_name) expression
type_name
为新类型名称,expression
为表达式。
(float) a; //将变量 a 转换为 float 类型
(int)(x+y); //把表达式 x+y 的结果转换为 int 整型
(float) 100; //将数值 100(默认为int类型)转换为 float 类型
#include <stdio.h>
int main(){
int sum = 103; //总数
int count = 7; //数目
double average; //平均数
average = (double) sum / count;
printf("Average is %lfn", average);
return 0;
}
Average is 14.714286
sum 和 count 都是 int 类型,如果不进行干预,那么sum / count
的运算结果也是 int 类型,小数部分将被丢弃;虽然是 average 是 double 类型,可以接收小数部分,但是心有余力不足,小数部分提前就被“阉割”了,它只能接收到整数部分,这就导致除法运算的结果严重失真。
为了达到这个目标,我们只要将 sum 或者 count 其中之一转换为 double 类型即可。上面的代码中,我们将 sum 强制转换为 double 类型,这样sum / count
的结果也将变成 double 类型,就可以保留小数部分了,average 接收到的值也会更加精确。
类型定义
C 语言提供了typedef关键字,你可以使用它来为类型取一个新的名字。
typedef unsigned char BYTE;
在这个类型定义之后,标识符 BYTE 可作为类型 unsigned char 的缩写,例如:
BYTE b1, b2;
也可以使用typedef来为用户自定义的数据类型取一个新的名字
#include <stdio.h>
#include <string.h>
typedef struct Books
{
char title[50];
char author[50];
char subject[100];
int book_id;
} Book;
int main( )
{
Book book;
strcpy( book.title, "C 教程");
strcpy( book.author, "Runoob");
strcpy( book.subject, "编程语言");
book.book_id = 12345;
printf( "书标题 : %sn", book.title);
printf( "书作者 : %sn", book.author);
printf( "书类目 : %sn", book.subject);
printf( "书 ID : %dn", book.book_id);
return 0;
}
书标题 : C 教程
书作者 : Runoob
书类目 : 编程语言
书 ID : 12345
#define 是 C 指令,用于为各种数据类型定义别名,与 typedef 类似,但是它们有以下几点不同:
- typedef 仅限于为类型定义符号名称,#define 不仅可以为类型定义别名,也能为数值定义别名,比如可以定义 1 为 ONE。
- typedef 是由编译器执行解释的,#define 语句是由预编译器进行处理的。
#define TRUE 1
#define FALSE 0
int main( )
{
printf( "TRUE 的值: %dn", TRUE);
printf( "FALSE 的值: %dn", FALSE);
return 0;
}
TRUE 的值: 1
FALSE 的值: 0
sizeof运算符
sizeof是C语言的一种单目操作符,如C语言的其他操作符++、--等。它并不是函数sizeof操作符以字节形式给出了其操作数的存储大小。操作数可以是一个表达式或括在括号内的类型名。操作数的存储大小由操作数的类型决定。
sizeof的使用方法
1、用于数据类型
sizeof使用形式: sizeof(type)
数据类型必须用括号括住: sizeof(int)
2、用于变量
sizeof使用形式: sizeof(var_name) 或 sizeof var_name
变量名可以不用括号括住.如sizeof (var_name),sizeof var_name等都是正确形式
带括号的用法更普遍,大多数采用这种形式。注意:sizeof操作符不能用于函数类型,不完全类型或位字段。
不完全类型指具有未知存储大小的数据类型,如未知存储大小的数组类型、未知内容的结构或联合类型、void类型等。
例如:
sizeof(max) --若此时变量max定义为int max();
sizeof(char_v) --若此时char_v定义为char char_v[MAX]且MAX未知,
sizeof(void)
以上都是不正确形式。
ANSI C正式规定字符类型为1字节。
sizeof(char) = 1;
sizeof(unsigned char) = 1;
sizeof(signed char) = 1;
其他类型在ANSI C中没有具体规定,大小依赖于实现。
sizeof(int) = 4;
sizeof(unsigned int) = 4;
sizeof(short int) = 2;
sizeof(unsigned short) = 2;
sizeof(long int) = 4;
sizeof(unsigned long) = 4;
sizeof(float) = 4;
sizeof(double) = 8;
sizeof(long double) = 12;
当操作数具有数组类型时,其结果是数组的总字节数。
例如:
char a[5];
int b[5];
sizeof(a) = 5;
sizeof(b) = 20;
当操作数是具体的字符串或者数值时,会根据具体的类型进行相应转化。
例如:
sizeof(8) = 4; //自动转化为int类型
sizeof(8.8) = 8; //自动转化为double类型,注意,不是float类型
sizeof("ab") = 3 //自动转化为数组类型,
当操作数是指针时,sizeof依赖于编译器。Microsoft C/C++7.0中,near类指针字节数为2,far、huge类指针字节数为4。一般Unix/Linux的指针字节数为4。
例如:
char *p; //Linux中
sizeof(p) = 4;
sizeof与其他操作符的关系
sizeof的优先级为2级,比/、%等3级运算符优先级高。它可以与其他操作符一起组成表达式:
例如:
int i = 10;
i * sizeof(int);