1.数据类型介绍
数据类型分为内置类型,自定义类型和.
内置类型包括:字符型,整型,浮点型,布尔型.
自定义类型包括:数组(char),结构体(struct),枚举(enum),联合体(union).
1.1 字符型
char
[signed] char
unsigned char
1.2 整型
//短整型
short [int]
[signed] short [int]
unsigned short [int]
//整型
int
[signed] int
unsigned int
//⻓整型
long [int]
[signed] long [int]
unsigned long [int]
//更⻓的整型
//C99中引⼊
long long [int]
[signed] long long [int]
unsigned long long [int]
1.3 浮点型
float
double
long double
1.4 布尔类型
C 语⾔原来并没有为布尔值单独设置⼀个类型,而是使⽤整数 0 表示假,非零值表示真。 在 C99 中也引入了 布尔类型 ,是专门表示真假的。
_Bool
布尔类型的使用得包含头文件布尔类型变量的取值是:true或者false.
#define bool _Bool
#define false 0
#define true 1
示意代码:
_Bool flag = true;
if (flag)
printf("i like C\n");
1.5 各种数据类型的长度
1.5.1 sizeof()操作符
sizeof是一个关键字,也是一个操作符,用于计算sizeof类型操作符的长度,单位是字节.
sizeof 操作符的操作数可以是类型,也可是变量或者表达式。
sizeof( 类型 )
sizeof 表达式
sizeof 的计算结果返回值是 size_t 类型的,并且size_t是一种无符号的整数.
几个有关sizeof的例子:
#include <stdio.h>
int main()
{
int a = 10;
printf("%zd\n", sizeof(a));
printf("%zd\n", sizeof a);//a是变量的名字,可以省略掉sizeof后边的()
printf("%zd\n", sizeof(int));
printf("%zd\n", sizeof(3 + 3.5));
return 0;
}
1.5.2 数据类型长度
#include <stdio.h>
int main()
{
printf("%zd\n", sizeof(char));
printf("%zd\n", sizeof(_Bool));
printf("%zd\n", sizeof(short));
printf("%zd\n", sizeof(int));
printf("%zd\n", sizeof(long));
printf("%zd\n", sizeof(long long));
printf("%zd\n", sizeof(float));
printf("%zd\n", sizeof(double));
printf("%zd\n", sizeof(long double));
return 0;
}
在vs2022 x64环境下输出结果如下:
1
1
2
4
4
8
4
8
8
1.5.3 sizeof中表达式不计算
#include <stdio.h>
int main()
{
short s = 2;
int b = 10;
printf("%d\n", sizeof(s = b+1));
printf("s = %d\n", s);
return 0;
}
2. signed 和 unsigned
C 语⾔使⽤ signed 和 unsigned 关键字修饰字符型和整型类型的.
signed 关键字,表示⼀个类型带有正负号,包含负值.
unsigned 关键字,表示该类型不带有正负号,只能表⽰零和正整数.
对于 int 类型,默认是带有正负号的,也就是说 int 等同于 signed int.
一般情况下,signed是不写的.
注:
char也可以设置成signed和unsigned
signed char c;
unsigned char c;
注意,C 语言规定 char 类型默认是否带有正负号,由当前系统决定. 这就是说, char 不等同于,signed char ,它有可能是 signed char ,也有可能是 unsigned char . 这⼀点与 int 不同, int 就是等同于 signed int .
3. 数据类型的取值范围
limits.h 文件中说明了整型类型的取值范围。
float.h 这个头文件中说明浮点型类型的取值范围。
为了代码的可移植性,需要知道某种整数类型的极限值时,应该尽量使用这些常量。
• SCHAR_MIN , SCHAR_MAX :signed char 的最小值和最大值。
• SHRT_MIN , SHRT_MAX :short 的最小值和最大值。
• INT_MIN , INT_MAX :int 的最小值和最大值。
• LONG_MIN , LONG_MAX :long 的最小值和最大值。
• LLONG_MIN , LLONG_MAX :long long 的最小值和最大值。
• UCHAR_MAX :unsigned char 的最大值。
• USHRT_MAX :unsigned short 的最大值。
• UINT_MAX :unsigned int 的最大值。
• ULONG_MAX :unsigned long 的最大值。
• ULLONG_MAX :unsigned long long 的最大值。
4.变量
4.1 变量的创建
定义:c语言中将经常变化的值成为变量.
变量创建格式如下:
data_type name;
数据类型 变量名
例子
int age; //整型变量
char ch; //字符变量
double weight; //浮点型变量
变量的初始化
int age = 18;
char ch = 'w';
double weight = 48.0;
unsigned int height = 100;
4.2 变量的分类
• 全局变量:在大括号外部定义的变量就是全局变量 全局变量的使用范围更广,整个工程中想使用,都是有办法使用的。
• 局部变量:在大括号内部定义的变量就是局部变量 局部变量的使用范围是比较局限,只能在自己所在的局部范围内使用的
例子如下:
#include <stdio.h>
int global = 2023;//全局变量
int main()
{
int local = 2018;//局部变量
printf("%d\n", local);
printf("%d\n", global);
return 0;
}
注:当局部变量和全局变量的名字相同的时候,局部变量优先使用.
局部变量和全局变量的存储.
内存分三个模块:栈区,堆区,静态区.
它们分别存储什么?
栈区:局部变量,函数参数.
堆区:动态内存管理,malloc函数,calloc函数,realloc函数,free函数.
静态区:全局变量,静态变量.
5.算术操作符
算术操作符:+、-、*、/、%
5.1 +和-
用于计算加法和减法.
5.2 *
用于计算乘法.
5.3 /
用于计算除法
5.4 %
运算符 % 表示求模运算,即返回两个整数相除的余值。这个运算符只能用于整数,不能用于浮点数.
示例如下:
#include <stdio.h>
int main()
{
int x = 6 % 4; // 2
return 0;
}
负数求模的规则是,结果的正负号由第⼀个运算数的正负号决定。
#include <stdio.h>
int main()
{
printf("%d\n", 11 % -5); // 1
printf("%d\n",-11 % -5); // -1
printf("%d\n",-11 % 5); // -1
return 0;
}
上⾯示例中,第⼀个运算数的正负号( 11 或 -11 )决定了结果的正负号。
6. 赋值操作符:=和复合赋值
初始化:创建一个变量之后给它一个值叫初始化.
赋值:接着初始化之后,再给这个变量一个值叫赋值.
示例
int a = 100;//初始化
a = 200;//赋值
7.单目操作符
单目操作符有:++、--、+、-
7.1++和--
++是⼀种自增的操作符,又分为前置++和后置++,--是⼀种自减的操作符,也分为前置--和后置--
7.1.1 前置++
示例
int a = 10;
int b = ++a;//++的操作数是a,是放在a的前⾯的,就是前置++
printf("a=%d b=%d\n",a , b);
要点:先+1,后使用;
a原来是10,先+1,后a变成了11,再使⽤就是赋值给b,b得到的也是11,所以计算技术后,a和b都 是11,相当于这样的代码:
int a = 10;
a = a+1;
b = a;
printf("a=%d b=%d\n",a , b);
7.1.2 后置++
int a = 10;
int b = a++;//++的操作数是a,是放在a的后⾯的,就是后置++
printf("a=%d b=%d\n",a , b);
要点:先使用,后+1.
7.1.3 前置--
同理,只是把加1,换成了减1; 要点:先-1,后使用
int a = 10;
int b = --a;//--的操作数是a,是放在a的前⾯的,就是前置--
printf("a=%d b=%d\n",a , b);//输出的结果是:9 9
7.1.4 后置--
同理后置--类似于后置++,只是把加⼀换成了减⼀
要点:先使用,后-1
int a = 10;
int b = a--;//--的操作数是a,是放在a的后⾯的,就是后置--
printf("a=%d b=%d\n",a , b);//输出的结果是:9 10
7.2 + 和 -
这里的+是正号,-是负号,都是单目操作符。
8. 强制类型转换
示例
int a = (int)3.14;//意思是将3.14强制类型转换为int类型,这种强制类型转换只取整数部分
9. scanf和printf介绍
9.1 printf
9.1.2 占位符
所谓 “占位符”,就是这个位置可以用其他值代入。
// 输出 There are 3 apples
#include <stdio.h>
int main()
{
printf("There are %d apples\n", 3);
return 0;
}
上面示例中, There are %d apples\n 是输出文本,里面的 %d 就是占位符,表⽰这个位置要用其他值来替换。占位符的第⼀个字符⼀律为百分号 % ,第⼆个字符表⽰占位符的类型, %d 表示这 ⾥代⼊的值必须是⼀个整数。
printf() 的第⼆个参数就是替换占位符的值,上⾯的例子是整数 3 替换 %d 。执行后的输出结果 就是 There are 3 apples 。
常用的占位符除了 %d ,还有 %s 表示代入的是字符串。
9.1.3 占位符列举
• %a :⼗六进制浮点数,字⺟输出为⼩写。
• %A :⼗六进制浮点数,字⺟输出为⼤写。
• %c :字符。
• %d :⼗进制整数。
• %e :使⽤科学计数法的浮点数,指数部分的 e 为⼩写。
• %E :使⽤科学计数法的浮点数,指数部分的 E 为⼤写。
%i :整数,基本等同于 %d 。
• %f :⼩数(包含 float 类型和 double 类型)。
• %g :6个有效数字的浮点数。整数部分⼀旦超过6位,就会⾃动转为科学计数法,指数部分的 e 为⼩写。
• %G :等同于 %g ,唯⼀的区别是指数部分的 E 为⼤写。
• %hd :⼗进制 short int 类型。
• %ho :⼋进制 short int 类型。
• %hx :⼗六进制 short int 类型。
• %hu :unsigned short int 类型。
• %ld :⼗进制 long int 类型。
• %lo :⼋进制 long int 类型。
• %lx :⼗六进制 long int 类型。
• %lu :unsigned long int 类型。
• %lld :⼗进制 long long int 类型。
• %llo :⼋进制 long long int 类型。
• %llx :⼗六进制 long long int 类型。
• %llu :unsigned long long int 类型。
• %Le :科学计数法表⽰的 long double 类型浮点数。
• %Lf :long double 类型浮点数。
• %n :已输出的字符串数量。该占位符本⾝不输出,只将值存储在指定变量之中。
• %o :⼋进制整数。
• %p :指针。
• %s :字符串。
• %u :⽆符号整数(unsigned int)。
• %x :⼗六进制整数。
• %zd : size_t 类型。
• %% :输出⼀个百分号。
9.1.4 赋值忽略符
有时,用户的输入可能不符合预定的格式。
#include <stdio.h>
int main()
{
int year = 0;
int month = 0;
int day = 0;
scanf("%d-%d-%d", &year, &month, &day);
printf("%d %d %d\n", year, month, day);
return 0;
}
上面示例中,如果用户输⼊ 2020-01-01 ,就会正确解读出年、月、日。问题是用户可能输⼊其他 格式,比如 2020/01/01 ,这种情况下, scanf() 解析数据就会失败。 为了避免这种情况, scanf() 提供了⼀个赋值忽略符(assignment suppression character) * 。 只要把 * 加在任何占位符的百分号后⾯,该占位符就不会返回值,解析后将被丢弃。
#include<stdio.h>
int main()
{
int year = 0;
int month = 0;
int day = 0;
scanf("%d%*c%d%*c%d", &year, &month, &day);
printf("%d %d %d",year,month,day);
return 0;
}
上⾯示例中, %*c 就是在占位符的百分号后面,加入了赋值忽略符 * ,表示这个占位符没有对应的变量,解读后不必返回。