基本类型
整型
整型存在六种分类
名称 | 表示 | 长度/字节 | 范围(long型长度以8记) |
---|---|---|---|
整型 | int | 4 | -2^31 至 2^31-1 |
长整型 | long | 4或8 | -2^63 至 2^63-1 |
短整型 | short | 2 | -2^15 至 2^15-1 |
无符号整型 | unsigned int | 4 | 0 至 2^32-1 |
无符号长整型 | unsigned long | 4或8 | 0 至 2^64-1 |
无符号短整型 | unsigned short | 2 | 0至 2^16-1 |
#include<stdio.h>
//简单的测试占用空间程序
int main(){
int Int = 0;
long Long = 0;
short Short = 0;
unsigned int UI = 0;
unsigned long UL = 0;
unsigned short US= 0;
long long LL = 0;
unsigned long long ULL = 0;
printf("int型的占用空间:%d\nlong型的占用空间:%d\nshort型的占用空间:%d\n",sizeof(Int),sizeof(Long),sizeof(Short));
printf("unsigned int型的占用空间:%d\nunsigned long型的占用空间:%d\nunsigned short型的占用空间:%d\n",sizeof(UI),sizeof(UL),sizeof(US));
printf("long long型的占用空间:%d\nusigned long long型的占用空间:%d",sizeof(LL),sizeof(ULL));
return 0;
}
可以注意到int是4个字节也就是4byte等于32bit,int型在不同编译器中位数可能有所不同。
实型/浮点型
名称 | 表示 | 长度/字节 |
---|---|---|
单精度浮点型 | float | 4 |
双精度浮点型 | double | 8 |
浮点型表示形式
- 小数形式:直接以带小数的实数形式表示
- 指数形式:也即科学计数法,形式为aEb或aeb,其中a代表科学计数法中的因数a,E或e代表幂的底为10,b代表10的幂次。例如,19971400000000=1.99714E13。
字符型
字符类型 char 占用长度:1字节,1byte=8bit
可储存256个字符,也即ASCII码中指定的字符。
枚举类型
定义方式为:
enum typeName{ valueName1, valueName2, valueName3, ...... };
值得注意的是:
-
valueName1等变量为整型常量,默认为从0开始递增,依次为0,1,2……,如果定义为valueName = 1,那么其中值便依次为1,2,3……
-
枚举列表中的valueName1、valueName2、valueName3这些标识符的作用范围是全局的(严格来说是 main() 函数内部),不能再定义与它们名字相同的变量。
-
valueName1、valueName2、valueName3等都是常量,不能对它们赋值,只能将它们的值赋给其他的变量。
构造类型
数组类型 []
定义:数组是具有相同类型的一组有序数据的集合,数组在内存中占用一段连续的存储空间。
字符数组
一般使用一维字符数组,定义与初始化如下
#include<stdio.h>
#include<string.h>
int main(){
//声明一个长度为10的字符数组
//声明后不初始化便使用很可能会造成意料之外的结果,应初始化或赋值后再使用
char s0[20];
//声明并赋值
char s1[20] = {"Hello World!"};
char s2[20] = {'H','e','l','l','o',' ','W','o','r','l','d','!'};
char s3[20] = {'H','e','l','l','o',' ','W','o','r','l','d','!','\0'};
char s4[] = {"Hello World!"};
char s5[20] = "Hello World!" ;
printf("s0字符串为:%s\ns1字符串为:%s\ns2字符串为:%s\ns3字符串为:%s\ns4字符串为:%s\ns5字符串为:%s\n",s0,s1,s2,s3,s4,s5);
if(!strcmp(s1,s2))
printf("s1与s2赋值方式等价\n");
if(!strcmp(s1,s5))
printf("s1与s5赋值方式等价\n");
if(!strcmp(s2,s3))
printf("系统自动赋了字符数组结束符\\0\n");
if(!strcmp(s1,s4))
printf("字符数组长度无关,只比较到\\0");
return 0;
}
TODO:字符串输出流读写函数超链接
一维数组
定义:类型名 数组名[常量表达式]
值得注意的是:
- 常量表达式(确定数组的长度):可以包含整型的常量和符号常量(以const与#define定义),不能包含变量。
- C语言不允许对数组的长度动态定义。
- 数组一经定义,C语言编译系统就在内存中分配一段连续的空间,用来存储数组个元素的值。
- 数组名表示一端连续空间的起始地址
数组引用:
数组名[下标],例:a[5],a[i+j]
注:下标:可以是整型,也可以是整型表达式;只能是逐个引用,循环遍历数组
初始化
若没有对数组元素赋值,则其值是随机值;初始化是在给数组分配空间时进行的赋值。
1)完全初始化 int a[10]={1,2,3,4,5,6,7,8,9,10};
2)部分初始化 int a[10]={1,2,3,4,5};
3)省略数组长度初始化 int a[]={1,2,3,4,5,6,7,8,9,10};
注:部分初始化,没有赋值的自动补0或0.0;如果超出长度,编译会出错;省略数组长度的初始化,有多少个元素,就默认是多少长度。
二维数组
定义:类型名 数组名[常量表达式1][常量表达式2]; 例如int num[2][3];
初始化
完全初始化:
按行初始化:int num[3][3] = {{1,2,3},{4,5,6}{7,8,9}};
按顺序初始化:int num[3][3] = {1,2,3,4,5,6,7,8,9};
部分初始化:
为某些行的部分元素赋值:int num[3][3] = {{1,2},{3,4}{5}};
给部分行的元素赋值:int num[3][3] = {{1,2,3},{}{4,5,6}};
给部分元素赋值:int num[3][3] = {1,2};
省略数组长度初始化:
按行书写:按照大括号的个数确定第一维的长度
按顺序书写:第二维长度能除完初始化值的个数,则第一维长度=个数/第二维长度,否则,第一维长度=个数/常量表达式+1(?)
值得注意的是:
- 常用于矩阵的存放以及表格阵列
- 按行存放
- a[1],a[2]在二维数组中不能当作下标使用,其代表的是一个一维数组名,也即一个数组的起始地址常量。
结构体与联合体
**结构体(struct)**是由一系列具有相同类型或不同类型的数据构成的数据集合,也叫结构。
定义
以整型链表为例
//定义方式1
struct LinkNode{
int data; //数据域
struct LinkNode *next; //指针域
}LinkList;
//定义方式2
struct LinkNode{
int data; //数据域
struct LinkNode *next; //指针域
};
struct LinkNode Linklist;
初始化
LinkNode linklist = {1,NULL};
也可以
LinkNode linklist;
linklist.data = 1;
linklist.next = NULL;
数组定义
//虽然用链表并不算严谨
LinkNode linklist[10];
TODO:结构体占用空间大小详解
引用
linklist.data = 1;
对于指针的引用
#include<stdio.h>
struct student{
int num;
char name[10];
int age;
char sex[10];
};
int main(){
student var = {1,"shazi",25,"male"};
student *pointerVar = &var;
printf("%d,%s,%d,%s\n",pointerVar->age,pointerVar->name,pointerVar->num,pointerVar->sex);
printf("%d,%s,%d,%s",(*pointerVar).age,(*pointerVar).name,(*pointerVar).num,(*pointerVar).sex);
return 0;
}
->所表示的与 (*指针). 一样
联合体
union 共用体名{
成员列表
};
union data{
int n;
char ch;
double f;
};
union data a, b, c;
值得注意的是:
结构体和共用体的区别在于:结构体的各个成员会占用不同的内存,互相之间没有影响;而共用体的所有成员占用同一段内存,修改一个成员会影响其余所有成员。
结构体占用的内存大于等于所有成员占用的内存的总和(成员之间可能会存在缝隙),共用体占用的内存等于最长的成员占用的内存。共用体使用了内存覆盖技术,同一时刻只能保存一个成员的值,如果对新的成员赋值,就会把原来成员的值覆盖掉。
指针类型
在冯·诺依曼体系中,储存器中的指令与数据被同等看待,存储器按地址访问,顺序编址。
指针,其实就是一个地址;地址也是指针。
定义
datatype *name;
或者
datatype *name = value;
其所表达的是name作为指针,指向一个内存空间。datatype表示的是name所指向的对象的类型。
在使用时,使用*name便可取得name指针所指向空间中的具体数据。
#include<stdio.h>
int main(){
int *a,b = 3,c;
a = &b; //指针a的值取到了b的地址
c = *a + b; //*a取到了a指针指向的空间也就是b中的值
printf("%d\n",c);
//b的数值变化
b = b-1;
c = *a + b;
printf("%d\n",c);
//*a的数值变化
*a = *a-1;
c = *a + b;
printf("%d\n",c);
return 0;
}
空类型
空类型,即无值类型或者叫做空值类型,使用关键字void表示。
C语言中的void类型,代表任意类型,而不是空的意思。任意类型是表示其类型是未知的,未指定的。
void * 是void类型的指针。void类型的指针的含义是:这是一个指针变量,该指针指向一个void类型的数。void类型的数就是说这个数有可能是任意类型。
在函数的参数列表和返回值中,void代表的含义是:一个函数形参列表为void,表示这个函数调用时不需要给它传参。
返回值类型是void,表示这个函数不会返回一个有意义的返回值。所以调用者不需使用返回值。