第二章 C语言之数据
2.1 表现形式
数据的表现形式有常量和变量
常量
常量指的是在程序生命周期保持不变的数据,保存在只读数据段,通常有字符常量、字符串常量、整型常量、浮点常量
字符常量
'\n'
'\r'
字符串常量
"hello world"
整型常量
0xfe
250u
1000L
浮点常量
3.1415926f
1.989E30
变量
变量是内存区域可操作数据的代称
定义变量
定义变量会给变量分配内存,定义变量方法:类型名 + 变量名
char ch;
int a;
float b;
ch = '\0';
a = 1024;
b = 3.1415926f;
同时也可以在定义变量的时候进行变量赋值
int var = 1024; // 定义变量并赋值
声明变量
声明变量是一种可以让编译器确信存在一个具有该给定名称变量的操作,编译器将获得继续进一步编译的信号,而无需有关该变量的完整详细信息,声明变量变量不会分配内存
extern float pi = 3.1415926f; // 声明一个float变量,没有分配内存
float func(float r)
{
return 2 * pi * r;
}
存储类型
C语言有4种存储类型的变量:全局变量、局部变量、自动变量、静态变量
全局变量:在块或函数外部声明的变量称为全局变量,程序中的任何函数都能够更改全局变量的值,它的生存周期是整个程序的生命周期
int age = 10; // 定义一个全局变量
int main()
{
......
return 0;
}
局部变量:在块或函数内声明的变量类型,跟全局变量不同,它的生存局限于函数调用过程或者代码块执行过程
void func()
{
int i = 0; // 定义一个函数内部局部变量
{
int j = 1; // 定义一个代码块局部变量
}
}
自动变量:默认情况下,在块(在 C 语言中)内声明的每个变量本质上都是自动的。可以使用关键字auto
显式声明任何给定的自动变量
auto int i = 10; // 定义一个自动变量,等价于int i = 10;
静态变量:静态变量是用户使用static关键字声明的变量,该变量在各个函数调用之间保留给定值
void counter(int var)
{
static int cnt = 0; // 定义一个静态变量,该变量在函数调用期间始终能有效操作,指向唯一的内存地址
if(var % 5 == 0)
{
cnt++;
printf("cnt : %d\n", cnt);
}
}
2.2 数据类型
基本类型
字符类型,unsigned char
取值范围0-255(参考ASCII码表),signed char
取值范围-128-127,默认signed char = char
unsigned char ch = 'a';
signed char a = -128;
整型类型
- short类型,有
unsigned short
和signed short
两种类型,默认signed short = short - int类型,有
unsigned int
和signed int
两种类型,默认signed int = int - long类型,有
unsigned long
和signed long
两种类型,默认signed long = long - long long类型,有
unsigned long long
和signed long long
两种类型,默认signed long long = long long
类型 | 长度 | 最小值 | 最大值 |
---|---|---|---|
short | 2 | -32768 | 32767 |
unsigned short | 2 | 0 | 65535 |
int | 4 | -2147483648 | 2147483647 |
unsigned int | 4 | 0 | 4294967295 |
long | win : 4 / linux : 8 | -2^31 / -2^63 | -2^31-1 / 2^63-1 |
unsigned long | win : 4 / linux : 8 | 0 | 2^64-1 / 2^64-1 |
long long | 8 | -2^63 | 2^63-1 |
unsigned long long | 8 | 0 | 2^64-1 |
浮点类型,分为float
、double
、long double
三种
类型 | 长度 | 精度 |
---|---|---|
float | 4 | 6 |
double | 8 | 8 |
long double | 16 | 10 |
空类型,void类型可以用于修饰函数的返回值,表示该函数没有返回值
void func()
{
......
}
也可以用于修饰指针类型
int a = 1000;
void *p = (void *)&a;
复合类型
数组,是一系列相同数据类型的集合
int arr[] = {1, 3, 5, 7, 9};
字符串,是一系列相同字符数据类型的集合,本质也是一种数组
char p[] = "hello world";
结构体,是不同数据类型的组合
struc Example
{
char *name;
int a;
float b;
double c;
};
位域,通过指定结构体和联合成员的大小(以位为单位)。位字段的想法是,当我们知道一个字段或一组字段的值永远不会超过限制或在一个小范围内时,可以有效地使用内存。当我们的程序的存储空间有限时,使用 C 位字段
struct
{
int member_name1 : 4;
char member_name2 : 2;
short member_name3 : 3;
};
枚举,由一组整数常量即枚举值组成,每一个枚举值用于区分不同的类别,第一个枚举值默认从0开始,也可以显式指定枚举值
enum weekday
{
Mon = 0,
Tue,
Wed,
Thu,
Fri,
Sat,
Sun
};
指针,本质是数据的内存地址,属于整型数据,大小跟操作系统位数有关(32位操作系统是32位,64位操作系统是64位)
void *p1;
int val;
int *p2 = &val;