文档版本 | 更新时间 | 更新内容 |
---|---|---|
v1.0 | 2020-09-13 | 初稿完成 |
v1.1 | 2020-09-16 | 添加static关键字部分 |
数据类型 | 占用字节 | 范围 |
---|---|---|
char | 1 | -128 - 127 |
unsigned char | 1 | 0 - 255 |
short | 2 | |
unsigned short | 2 | |
int | 4 | |
unsigned int | 4 | |
long | 4 | |
unsigned long | 4 | |
long long(C99加入) | 8 | |
unsigned long long(C99加入) | 8 | |
float | 4 | |
double | 8 |
/**
* CPU:64bit
* OS:Windows10
* IDE:Clion
* Compiler:MinGW-64
*/
#include
int main() {
printf("char:%d\r\n", sizeof(char));
printf("short:%d\r\n", sizeof(short));
printf("int:%d\r\n", sizeof(int));
printf("long:%d\r\n", sizeof(long));
printf("long long:%d\r\n", sizeof(long long));
printf("float:%d\r\n", sizeof(float));
printf("double:%d\r\n", sizeof(double));
return 0;
}
运行结果为:
char:1
short:2
int:4
long:4
long long:8
float:4
double:8
int的长度会跟随CPU的不同而发生变化,比如:
所以通常情况下使用C头文件
中提供的数据类型:
同时,该头文件提供了数据类型的最大最小值宏定义,如下:
/* 7.18.2.1 Limits of exact-width integer types */
#define INT8_MIN (-128)
#define INT16_MIN (-32768)
#define INT32_MIN (-2147483647 - 1)
#define INT64_MIN (-9223372036854775807LL - 1)
#define INT8_MAX 127
#define INT16_MAX 32767
#define INT32_MAX 2147483647
#define INT64_MAX 9223372036854775807LL
#define UINT8_MAX 255
#define UINT16_MAX 65535
#define UINT32_MAX 0xffffffffU /* 4294967295U */
#define UINT64_MAX 0xffffffffffffffffULL /* 18446744073709551615ULL */
/**
* CPU:64bit
* OS:Windows10
* IDE:Clion
* Compiler:MinGW-64
*/
#include
#include
int main() {
int8_t a = -128, b = 127;
uint8_t c = 0, d = 255;
a = a - 1;
b = b + 1;
c = c - 1;
d = d + 1;
printf("a = %d, b = %d\r\n", a, b);
printf("c = %d, d = %d\r\n", c, d);
return 0;
}
运行结果如下:
a = 127, b = -128
c = 255, d = 0
原因:
详细说明参考博文:整数在计算机中的存储
① 局部变量:在函数内部定义,函数结束后变量自动销毁;
② 全局变量:在函数外部定义,整个文件内部都可以使用该变量,程序结束后销毁;
③ 外部变量:使用extern修饰,表示该变量在其它文件中定义为全局变量;
④ 静态变量:使用static修饰,表示该变量在定存中只有一份定义;
⑤ 易变变量:使用volatile修饰,表示该变量是易变的,防止编译器优化;
常量有两种:
① 使用const修饰符,作为只读变量:
const double pi = 3.1415926;
② 使用字面值:
#define PI 3.1415926
字面值的数据类型会被编译器自动识别:整数默认int,浮点数默认double,如果存不下则自动寻找更大的类型存储。
可以在数值后面加后缀,显示指出要使用的数据类型:
U或u
:unsignedL或l
:long int 或者Long doubleLL或ll
:long longF或f
:float/**
* CPU:64bit
* OS:Windows10
* IDE:Clion
* Compiler:MinGW-64
*/
#include
#include
int main() {
float a, b;
b = 2.0e20 + 1.0;
a = b - 2.0e20;
printf("a = %f\r\n", a);
return 0;
}
运行结果为:
a = 4008175468544.000000
因为float只能存储小数点后6位的精度,所以肯定错误。
如果将2.0e20改为2.0e4,则运行结果为:
a = 1.000000
浮点数的值:2.0e4=20000,2.0e-4=0.0002
因为浮点数不能精准的存储,所以需要在编程时注意。
eg:
/**
* CPU:64bit
* OS:Windows10
* IDE:Clion
* Compiler:MinGW-64
*/
#include
#include
int main() {
float a = 99.9;
printf("a = %f\r\n", a);
return 0;
}
运行结果为:
a = 99.900002
常用的一些占位符如下表:
占位符 | 说明 |
---|---|
%d | int |
%ld | long |
%c | char |
%f | float |
%lf | double |
%x | int、short、long |
%o | int、short、long |
%s | 字符串 |
%e或者%E | 使用e计数法输出浮点数 |
%x或者%X | 无符号十六进制输出整数 |
%% | 打印一个百分号 |
头文件:
#include
用法:
printf("字符串");
printf("字符串 占位符1 占位符2", 输出参数1, 输出参数2);
在%
和转换字符
之间插入修饰符可修饰基本的转换说明。
scanf的作用:将用户从键盘输入的字符串转换为字符、字符串、整数、浮点数。
特别注意!输入参数是变量的地址!
头文件:
#include
scanf("占位符", 输入参数);
//这种用法,在输入的时候必须将非占位符也输入
scanf("非占位符 占位符", 输入参数);
scanf函数使用空白(换行符、制表符、空格)把输入分成多个字段,在依次把转换说明和字段匹配时跳过空白。
/**
* CPU:64bit
* OS:Windows10
* IDE:Clion
* Compiler:MinGW-64
*/
#include
int main() {
int a;
float b;
char c[20];
scanf("%d%f%s", &a,&b, c);
printf("a is %d, b is %.2f,c is %s\r\n", a, b, c);
return 0;
}
运行结果如下:
1234124
1.23452
hello
a is 1234124, b is 1.23,c is hello
① 在printf中,*修饰符用来代替字段宽度,由变量指定。
② 在scanf中,*修饰符表示跳过这个转换说明符。
① 算术运算符:
+、-、*、/
C语言中,两个整数之间用
/
运算,结果也是整数。
② 关系运算符:
、>=、<、<=、!=、==
③ 逻辑运算符:
!、&&、||
④ 赋值运算符:
=、+=、-=、/=、*=
算术 > 关系 > 逻辑 > 赋值
特别注意!case之后的标号只允许字面常量,且是整型。(变量、const只读变量、浮点数都是错误的)。
函数是C语言的基本单位。
函数返回值类型 函数名(函数参数列表);
函数返回值类型 函数名(函数参数列表)
{
函数主体;
return 返回值;
}
解决同类型数据的存储问题。
① 定义数组:
<数据类型> <数组名>[数组中元素个数];
② 初始化数组
完全初始化:
int a[5] = {
1,2,3,4,5};
不完全初始化,未被初始化的元素为0:
int a[5] = {
1,2,3};
不初始化,所有元素都是垃圾值:
int a[5];
清零:
//原理:第一个元素初始化为0,属于不完全初始化,所以全部为0
int a[5] = {
0};
eg:
/**
* CPU:64bit
* OS:Windows10
* IDE:Clion
* Compiler:MinGW-64
*/
#include
#include
int main() {
int a[5];
int i;
for (i = 0; i < 5; i++) {
printf("%d ", a[i]);
}
printf("\r\n");
return 0;
}
运行结果为:
8 0 73 0 1647344
③ 数组可以进行的操作:
① 定义:
//一个3行4列的二维数组
int a[3][4];
② 初始化
整体赋值:
int a[3][4] = {
1,2,3,4,5,6,7,8,9,10,11,12};
整体赋值的另外一种写法:
int a[3][4] = {
{
1,2,3},
{
4,5,6},
{
7,8,9},
{
10,11,12}
};
③ 访问(按下标):
a[i][j]
④ 二维数组的操作:
物理内存是线性连续的,所以多维数组本质并不存在。
3行4列的二维数组,本质上是3个元素一维数组,只不过每个元素也是含有4个小元素的一维数组。
static关键字表示静态的,可以用来修改变量和函数。
static关键字修饰变量后,表示该变量是静态的,无论定义多少次,在内存中只有一份。
比如下面的示例:
#include
int test(void)
{
int ret;
static int id = 0;
ret = id++;
return ret;
}
int main()
{
int id;
for (int i = 0; i < 10; i++) {
id = test();
printf("id = %d\r\n", id);
}
return 0;
}
运行结果为:
id = 0
id = 1
id = 2
id = 3
id = 4
id = 5
id = 6
id = 7
id = 8
id = 9
static修饰静态函数,表示此函数只能在本文件中使用。