C语言的数据类型分为基本数据类型、构造类型、指针类型、枚举类型和空类型等几种。
一、基本数据类型
1.1 整型int
1>short int、short: 占2个字节,占位符:%d %i
2>long int、long: 占8个字节,占位符:%ld
3>signed int、signed: 占4个字节,占位符:%d %i
4>unsigned int、unsigned: 占4个字节,占位符:%zd
1.2 浮点型float\double
1>float: 占4个字节,占位符:%f
2>double 占8个字节,占位符:%f
3>double类型的精度要比float精度要高
4>占位符%f默认保留小数点后6位。当要保留精确位数的小数时,可以在%和f中间用.位数表示,如要保留小数点后两位,占位符可用%.2f表示。
5>为了跟double区分开来,float 型数据都是以f结尾的,比如5.43f、-2.3f、0.0f。需要注意的是,绝对不能有10f这样格式的,编译器会直接报错,只有小数才允许加上f。
1.3字符char
1>char 占1个字节,占位符:%c
2>char类型保存在内存中的是它的ASCII值,如‘A’保存在内存中的值是65,当输出占位符用%c表示时,输出A。当输出占位符用%d表示时,输出65。
二、构造类型
2.1 数组
1>只能由同一种类型的数据组成
2>定义:数据类型 数组名[元素个数]
3>声明并初始化的几种方式
int ages[5]={0,1,2,3,4}; // 全部元素初始化
int ages[5]={0,1}; //部分元素初始化,其余的元素默认初始化为0
int ages[5]={[3]=3,[4]=4}; //指定下标元素初始化,其余的元素默认初始化为0
int ages[]={0,1,2}; //省略元素个数进行初始化,数组会根据赋值过去的元素动态分配个数和内存给数组
4>数组可以作为函数参数进行传递,作为参数时可以省略元素个数,并且传递的是整个数组的地址,修改函数形参数组元素的值,会影响到外面的实参数组
5>数组当做函数参数传递时,会当做指针变量来使用,指针变量在64bit编译器环境下,占据8个字节。因此在C语言中通过形参是获取不到数组的实际长度的,需要传参的时候把数组长度通过形参的形式传递到函数内部。
/*
设计一个函数,找出整型数组元素的最大值
*/
#include <stdio.h>
int maxOfArray(int array[], int length)
{
// 数组当做函数参数传递时,会当做指针变量来使用,指针变量在64bit编译器环境下,占据8个字节
//int size = sizeof(array);
//printf("array=%d\n", size); //8
// 1.定义一个变量存储最大值(默认就是首元素)
int max = array[0];
// 2.遍历所有元素,找出最大值
for (int i = 1; i<length; i++)
{
// 如果当前元素大于max,就用当前元素覆盖max
if (array[i] > max)
{
max = array[i];
}
}
return max;
}
int main()
{
int ages[] = {11, 90, 67, 150, 78, 60, 70, 89, 100};
//sizeof(ages)/sizeof(int)获取到的是数组的元素个数
int max = maxOfArray(ages, sizeof(ages)/sizeof(int));
printf("%d\n", max);
return 0;
}
2.2 结构体struct
1>可以由不同类型的数据组成
2>先定义类型,再利用类型定义变量
// 1.定义结构体类型
struct Person
{ // 里面的3个变量,可以称为是结构体的成员或者属性
int age; // 年龄
double height; // 身高
char *name; // 姓名
};
// 2.根据结构体类型,定义结构体变量
struct Person p = {20, 1.55, "jack"};
p.age = 30;
p.name = "rose";
struct Person p2 = {.height = 1.78, .name="jim", .age=30};//初始化时指定成员进行初始化
printf("age=%d, name=%s, height=%f\n", p.age, p.name, p.height);
4>结构体类型的作用域:定义在函数外面时,全局有效。即定义类型的那行开始,一直到文件结尾。定义在函数(代码块)内部时,局部有效,即从定义类型的那行开始,一直到函数(代码块)结束。
5>结构体类型不能重复定义
三、指针类型
1>作用:指针就是根据一个地址值,访问对应的存储空间。指针变量只能存储地址。
2>指针变量的定义:变量类型 *变量名
int *p; //指针变量p前面的int,指明指针变量p只能指向int类型的数据
3>间接操作变量的值
int *p;
int a=10;
p=&a;
*p=20; //*的作用:访问指向变量p指向的存储空间
4>指针变量可以作为方法的形参,在方法内对指针形参指向变量的修改,会影响到外面的实参
#include <stdio.h>
void change(int *n);
int main()
{
int a = 90;
change(&a);
printf("%d\n", a);
return 0;
}
void change(int *n)
{
*n = 10;
}
p=0;
p= NULL;
6>指针的其中一个应用情景:当一个参数需要返回多个值时,就可以用到指针。比如一个想在一个函数里面返回两个数的和跟差,可以通过把和作为返回值返回,把差的指针作为形参传进函数中,对差的值进行操作。
#include <stdio.h>
int sumAndMinus(int n1, int n2, int *n3);
int main()
{
int a = 10;
int b = 7;
// 存储和
int he;
// 存储差
int cha;
he = sumAndMinus(a, b, &cha);
printf("和是%d, 差是%d\n", he, cha);
return 0;
}
// 返回值是
int sumAndMinus(int n1, int n2, int *n3)
{
*n3 = n1 - n2;
return n1 + n2;
}
7>指针和字符串
定义字符串的2种方式:
7.1> 利用数组
char name[] = "itcast";
* 特点:字符串里面的字符是可以修改的
* 使用场合:字符串的内容需要经常修改
7.2> 利用指针
char *name = "itcast";
* 特点:字符串其实是一个常量字符串,里面的字符是不能修改
* 使用场合:字符串的内容不需要修改,而且这个字符串经常使用
四、枚举类型
1 >使用场合:当一个变量只允许有几个固定取值时
2 >先定义类型,再利用类型定义变量
enum Season
{
spring = 1,
summer,
autumn,
winter
};
// 2.定义枚举变量
enum Season ssummer;
//enum Season s = 100000; //C语言是弱语法,即使赋的值不是枚举中的值,也不报错。所以赋值的时候需要注意该枚举是怎样定义的。
五、空类型
1>void 表示函数没有返回值