本章简单介绍C语言基本数据类型 char、short、int、long int、longlong、float、double 以及各类型的指针、一维数组、二维数组、sizeof操作符等 主要是了解,各种类型初步介绍,点到为止,详细的介绍会在后续博客数据的存储篇中。
sizeof为单目操作符,作用为计算操作数类型的长度或变量内存空间大小(单位:字节)
1.sizeof 后面操作数为类型名 时要用()括起来
2.sizeof后面为变量时可以不用()括起来
二者得到的结果都是1,因为char类型占1个字节 ,即char类型创建的变量 内存空间大小也是1字节。
注意:每个操作数都应用()括起来保持一致,避免出现不必要的错误。
整形家族有char(字符型)、short(短整型)、int(整形)、long int(长整形)、longlong (更长的整形)。这里暂时介绍的是有符号的,具体的无符号后续在数据的存储中会介绍
看到这里就有疑惑了,char类型明明是字符类型为什么会在整形家族里,因为char实际在计算机内是以ASCLL码形式存储,所以实际是一个整形。
它用来声明定义一个变量,表示其类型为字符型。
例如char a =‘a’; 字符类型的数据要在两个单引号里
通过图可得 char类型占的字节大小为1,
short声明定义的变量为短整型变量。
从图中可以看出short的类型长度为2个字节
int整形类型声明定义的是一个整形变量
从图中看出int类型占4个字节
long int 类型为长整形类型,声明定义的变量为长整形变量
从图中看出long int 数据类型长度仍为4,
注意long int 可以简写为 long
longlong 为longlong int 更长的整形类型声明定义的整形变量内存空间是最大的。
从图中可得此类型的长度为8字节,是所有整形家族类型里类型长度最大的。
浮点型即为小数点类型 比如1.0 , 3.14等都为浮点型,
为什么被称作浮点型呢?
因为1.0可以被写作0.10x10 不同表达方式那个小数点可以左右浮动,故被称为浮点型。
float单精度浮点型声明定义代表变量是单精度类型的
由图可看出float单精度浮点型类型长度为4字节
注意1.0L后面的f是将1.0数据强制类型转化为float类型,因为默认编译器会将浮点数数据设为double类型
double 类型声明定义的变量为双精度浮点型
从图中可以看出double双精度浮点型类型长度为8个字节
单精度浮点型 只能保留7位有效数据
双精度浮点型 能保留16位有效数据
二者默认会保留后六位小数
从图中看出 float声明定义的变量 最后打印出来的值发生了精度偏差,而double按原样打印了出来。这也是它们取名单精度,双精度的缘故。
- 指针是内存中一个最小单元的编号,也就是地址
- 平时口语中说的指针,通常指的是指针变量,是用来存放内存地址的变量
指针是地址是编号,标明着内存空间在计算机内存里的位置,它是独一无二的。
在计算机内存里的空间是由一个个内存单元组成,每个内存单元长度为1个字节都有对应的编号即指针。
#include
int main()
{
int a = 10;//在内存中开辟一块空间
int *p = &a;//这里我们对变量a,取出它的地址,可以使用&操作符。
//a变量占用4个字节的空间,这里是将a的4个字节的第一个字节的地址存放在p变量
中,p就是一个之指针变量。
return 0;
}
a为一个整形变量,&a此时得到的就是一个整形指针,此时它为一个数据,要创建一个整形指针变量存储起来,此时 int *p为创建的整形指针变量,p就是一个指针变量。
指针变量可以是任何基本类型 如 字符型指针变量、整形指针变量
而其指针长度是多少呢?
由图可以看到 两个类型长度为8,但这只是在64位操作平台上而言,这些变量存储的是地址,大小都是相等的,且跟计算机平台位数有关,32位的 指针类型长度为4,64位的指针类型长度为8.
上图我将两变量赋值为NULL是空指针的意思,为了避免变量里是野指针,这块知识以后会详细讲到。
指针是c语言的灵魂,它有好处也有坏处,
好处:它可以直接访问它所指向的内存空间,对其空间里的数据进行操作,比如我这篇博客(单击此处传送门)里提到的swap自定义函数,通过指针解引用才能直接访问到内存空间使俩数进行交换。
坏处:使用不当会造成越界访问,内存泄漏等问题,因为指针你得指向明确已经建立好的内存空间,一旦指向不确定的内存空间对其解引用则会发生错误。
数组是一组相同类型元素的集合,暂时提到一维数组和二维数组
优点:数组里的元素在内存中是连续存放的
一维数组为一行,创建一维数组有3种方式
1.创建时指定了数组元素个数,可以不初始化
数组的初始化是指,在创建数组的同时给数组的内容一些合理初始值(初始化)
2.未指定数组元素但是对其完全初始化(每个元素都对应赋值)
数组未完全初始化,只初始化了一部分,则为初始化的元素默认为0
对于数组的使用介绍一个操作符: [] ,下标引用操作符。它其实就数组访问的操作符我们来看代码:
#include
int main()
{
int arr[10] = {0};//数组的不完全初始化
//计算数组的元素个数
int sz = sizeof(arr)/sizeof(arr[0]);
//对数组内容赋值,数组是使用下标来访问的,下标从0开始。所以:
int i = 0;//做下标
for(i=0; i<10; i++)//这里写10,好不好?
{
arr[i] = i;
}
//输出数组的内容
for(i=0; i<10; ++i)
{
printf("%d ", arr[i]);
}
return 0;
}
数组是使用下标来访问的
数组下标是从0开始的表示数组第一个元素
arr为数组名,当在sizeof(arr)时表示整个数组类型长度即数组的内存大小 为数组里所有元素内存大小之和, sizeof(arr[0])表示数组第一个元素类型长度,
int sz = sizeof(arr)/sizeof(arr[0]);这个式子就能让我们算出数组所有元素个数。
数组创建
int arr[3][4];
char arr[3][5];
double arr[2][4];
第一个[]内表示行,第二个[]表示列
数组初始化 int arr[3][4] = {1,2,3,4}; int arr[3][4] = {{1,2},{4,5}}; int
arr[][4] = {{2,3},{4,5}};
二维数组如果有初始化,行可以省略,列不能省略
看代码:
#include
int main()
{
int arr[3][4] = {0};
int i = 0;
for(i=0; i<3; i++)
{
int j = 0;
for(j=0; j<4; j++)
{
arr[i][j] = i*4+j;}
}
for(i=0; i<3; i++)
{
int j = 0;
for(j=0; j<4; j++)
{
printf("%d ", arr[i][j]);
}
}
return 0;
}
二维数组的使用也是通过下标的方式
数组的下标是有范围限制的。
数组的下规定是从0开始的,如果数组有n个元素,最后一个元素的下标就是n-1。
所以数组的下标如果小于0,或者大于n-1,就是数组越界访问了,超出了数组合法空间的访问。
C语言本身是不做数组下标的越界检查,编译器也不一定报错,但是编译器不报错,并不意味着程序就
是正确的,
所以程序员写代码时,最好自己做越界的检查
#include
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
int i = 0;
for(i=0; i<=10; i++)
{
printf("%d\n", arr[i]);//当i等于10的时候,越界访问了
}
return 0;
}
一维数组数组名做函数传参
数组名为首元素地址 所以作为参数传参为首元素地址传参
函数形参可以用一个指针变量接受或者对应的一维数组接受,此时接受的只是一个指针,不会开辟和数组一样大小的空间
二维数组数组名做函数传参
二维数组数组名表示首元素地址
而二维数组首元素为第一行,首元素地址为第一行的地址
函数形参可以用一个相同的二维数组接受可以省略行不能省略列
数组作为函数传参具体示例在我下一篇博客中三子棋游戏中会介绍
冒泡排序为一种排序方法,可以将数组里的数据按从大到小或从小到大排序
#include
void bubble_sort(int arr[])
{
int sz = sizeof(arr)/sizeof(arr[0]);//这样对吗?
int i = 0;
for(i=0; i<sz-1; i++)
{
int j = 0;
for(j=0; j<sz-i-1; j++)
{
if(arr[j] > arr[j+1])
{
int tmp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = tmp;
}
}
}
}
int main()
{
int arr[] = {3,1,7,5,8,9,0,2,4,6};
bubble_sort(arr);//是否可以正常排序?
for(i=0; i<sizeof(arr)/sizeof(arr[0]); i++)
{
printf("%d ", arr[i]);
}
return 0;
}
显然此冒泡函数设计出现了小问题导致了排序错误,
当数组传参的时候,实际上只是把数组的首元素的地址传递过去了。
所以即使在函数参数部分写成数组的形式: int arr[] 表示的依然是一个指针: int *arr 。
那么,函数内部的 sizeof(arr) 结果是4
#include
void bubble_sort(int arr[], int sz)//参数接收数组元素个数
{int i = 0;
for(i=0; i<sz-1; i++)
{
int j = 0;
for(j=0; j<sz-i-1; j++)
{
if(arr[j] > arr[j+1])
{
int tmp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = tmp;
}
}
}
//代码同上面函数
}
int main()
{
int arr[] = {3,1,7,5,8,9,0,2,4,6};
int sz = sizeof(arr)/sizeof(arr[0]);
bubble_sort(arr, sz);//是否可以正常排序?
int i;
for(i=0; i<sz; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
经过改正后最后实现了冒泡排序函数设计
本文对数据基本类型做了初步的讲解,点到为止,在后续的博客中会详细讲解到数据的各种使用方法和在计算机内部如何存储。
基于对这些基础知识的理解和巩固,下期博客将会带来三子棋和扫雷的游戏。
篇幅较大,内容有些仓促,希望各位见谅,文中有什么不正确的地方请指出,本人将第一时间改正。
写文不易,给个一键三连支持下吧~~~