C语言使用 signed 和 unsigned 关键字修饰字符型和整型类型的。
signed 关键字,表示一个类型带有正负号,包含负值;
unsigned 关键字,表示该类型不带有正负号,只能表示零和正整数。
对于 int 类型,默认是带有正负号的,也就是说 int 等同于 signed int。
由于这是默认情况,关键字 signed 一般省略不写,但是写了也不算错。
signed int a;
//等同于int a
int 类型也可以不带正负号,只表示非负整数。这是就必须使用关键字 unsigned 声明变量。
unsigned int a;
整数变量声明为 unsigned 的好处是,同样长度的内存能够表示的最大整数值,增大了一倍。比如,16位的 unsigned short int 的取值范围是:0~65535,最大值增大到了65535.32位的 signed int 的取值范围可以参看 limits.h 中给出的定义。
下面的定义是VS2022环境中,limits.h中相关定义。
#define SHRT_MIN -32768 //有符号16位整型的最小值
#define SHRT_MAX 32767 //有符号16位整型的最大值
#define USHRT_MAX 0xffff //无符号16位整型的最大值
#define INT_MIN -2147483647-1 //有符号整型的最小值
#define INT_MAX 2147483647 //有符号整型的最大值
unsigned int 里面的 int 可以省略,所以上面的变量声明也可以写成下面这样。
unsigned a;
字符类型 char 也可以设置 signed 和 unsigned 。
signed char c;//范围为 -128 到 127
unsigned char c;//范围为 0 到 255
注意,C语言规定 char 类型默认是否带有正负号,由当前系统决定。
这就是说,char 不等同于 signed char ,它有可能是 signed char ,也有可能是 unsigned char 。
这一点与 int 不同,int 就是等同于signed int 。
运算符 / 用来完成除法。
除法的两端如果是整数,执行的是整数除法,得到的结果也是整数。
#include
int main()
{
float x = 6 / 4;
int y = 6 / 4;
printf("%f\n", x);//输出1.000000
printf("%d\n", y);//输出1
return 0;
}
上面实例中,尽管变量 x 的类型是 float (浮点数),但是 6 / 4 得到的结果是 1.0 。而不是 1.5。原因就在于C语言里面的整数除法是整除,只会返回整数部分,丢弃小数部分。
如果希望得到浮点数的结果,两个运算数必须至少有一个浮点数,这时C语言就会进行浮点数除法。
#include
int main()
{
float x = 6.0 / 4;//或者写成 6 / 4.0
printf("%f\n", x);//输出1.500000
return 0;
}
上面实例中, 6.0 / 4 表示进行浮点数除法,得到的结果就是 1.5。
再看一个例子:
#include
int main()
{
int score = 5;
score =(score / 20) * 100;
printf("%d\n",score);
return 0;
}
上面的代码,你可能觉得经过运算,score 会等于 25,但是实际上 score 等于 0。这是因为 score / 20 是整除,会得到一个整数值 0,所以乘以 100 后得到的也是 0。
为了得到预想的结果,可以将除数 20 改成 20.0,让整除变成浮点数除法。
#include
int main()
{
float score = 5;
score =(score / 20.0) * 100;
printf("%lf\n",score);
return 0;
}
运算符 % 表示求模运算,即返回两个整数相除的余值。这个运算符只能用于整数,不能用于浮点数。
#include
int main()
{
int x = 6 % 4;//2
return 0;
}
负数求模的规则是,结果的正负号由第一个运算数的正负号决定。
#include
int main()
{
printf("%d\n",11 % -5);//1
printf("%d\n",-11 % -5);//-1
printf("%d\n",-11 % 5);//-1
return 0;
}
上面实例中,第一个运算数的正负号(11 或 -11)决定了结果的正负号。