数据类型难理解点 答疑
负数参与取余和整除运算规则?
取余(%):跟随前数(即与被除数保持一致)
整除(/):同正异负
#include<stdio.h>
#include<string.h>
int main()
{
printf("%d",10%6); //4
printf("%d",10%-6); //4
printf("%d",-10%6); //-4
printf("%d\n",-10%-6);//-4
printf("%d",10/6); //1
printf("%d",10/-6); //-1
printf("%d",-10/6); //-1
printf("%d\n",-10/-6);//1
return 0;
}
【运行结果】
-1 % 2 = -1
1 %-2 = 1
逻辑或、逻辑与组合
1. || 后面是逻辑与表达式,先看||前面的表达式
式1 || 式2 && 式3
式1 || (式2 && 式3)
这样理解:C语言编译器为了提高效率,规定“短路 ”的优先级 > && ,且该式子要以 || 分成左右两部分,C语言先判断 || 左边的部分是否为真,
若左边是真,则 || 右边的所有表达式都不再计算 ;若左边为假,则计算 || 右边的表达式是否为真 再计算整个表达式是否为真。
#include<stdio.h>
int main()
{
int a,b,c,f;
a=b=c=1;
//从本行到printf函数之间的句子每次只执行一条,其他保持注释
// f=++a||++b&&++c; //2,1,1,1
// 由于++a为(!0)真,所以将||右边的 ++b&&++c短路(即不再计算||右边,b与c都不会++)。整个表达式值为1
// f=++a||(++b&&++c); //2,1,1,1
// 由于++a为(!0)真,所以将||右边的 (++b&&++c) 短路(即不再计算||右边,b与c都不会++)。整个表达式值为1
f=(++b&&++c)||(++a&&++d); //1,2,2,1,1
// ||左边为真,所以||右边所有式子都不再计算
// f=--a||(++b&&++c); //0,2,2,1
// 由于--a为(0)假,所以计算 || 右边的 (++b&&++c) ,++b、++c都为真且都b、c都++了,所以整个表达式的值为1,
printf("%d,%d,%d,%d",a,b,c,f);
}
2.|| 前面是逻辑与表达式,先看逻辑与表达式
int main()
{
int a,b,c,f;
a=b=c=1;
//从本行到printf函数之间的句子每次只执行一条,其他保持注释
f=--a&&++b||++c; //0,1,2,1
//上式以||分为两部分,先计算||左边(假), 然后计算 || 右边(真),所以整个为真
f=++a&&++b||++c; //2,2,1,1
//上式以||分为两部分,先计算||左边(真), 因此短路 || 右边(不计算),且整个为真
printf("%d,%d,%d,%d",a,b,c,f);
}
== 只可以比较整型、字符型,浮点数和字符串不能用==比较
浮点型用fabs(),字符串用strcmp()
浮点数不能用 == 比较?
经断点调试,发现:执行到if(a==b)这句时,没有执行if分支,下一步直接跳转到了return 0;
因此,不可以。
测试使用double,测试float得到了同样的结果(如下)
测试源代码如下:
//两个浮点数不能用 == 比较?
#include<stdio.h>
int main()
{
double a=3.14,b=3.15;
if(a==b)
{
printf("%f",a);
}
return 0;
}
如何比较浮点型数据的大小?
通过math.h头文件下的fabs()函数,当浮点数a-b的值<一个很小很小的数时,我们就认为a、b是相等的。
函数名: fabs
功 能: 返回浮点数的绝对值
用 法: #include <math.h>
double fabs(double x);
如果将条件改为if (fabs(a-b) < 1e-11,则变为了不相等
if(fabs(a-b) < 1e-11) // 不相等
%f、%lf的区别?
scanf的格式控制符中,单精度用%f,双精度用%lf
printf的格式控制符中,单精度和双精度都用%f,双精度也可用%lf。
C语言的printf()函数的格式控制符中,之前只有%f,在C99以及C11加入了 %lf ,意味着C99之后%f和%lf都可用在输出中。
一般来说,CPU处理单精度浮点数的速度比处理双精度浮点数快。
详细参考:https://bbs.huaweicloud.com/blogs/268493
为什么int和long取值范围一样,在求阶乘和的问题中还要建议类型名定为long呢?
定义中的,是分隔符还是逗号运算符?
如下列代码,显然是逗号运算符。
short int a = 1, b = 2, c = a + b; //这里的逗号是逗号运算符而非分隔符
C语言中,定义时不赋值,哪些值为0,哪些值为随机数?
值为0:数组的元素部分赋初值(包括整型数组、实型数组、字符数组、结构体数组)、
static修饰的变量
值为随机数:数组整体不赋初值,普通变量(整型、实型、字符型)
int b[6] = { 'a','b','c','d' }; //整型数组部分元素赋初值
for (i = 0; i < 6; i++)
printf("%d ", b[i]); //97 98 99 100 0 0
char b[6] = { 'a','b','c','d' }; //字符数组部分元素赋初值
for (i = 0; i < 6; i++)
printf("%c ", b[i]); //a b c d
float b[6] = {32.51,63.36,5.9,95.6 }; //数组元素部分赋初值
for (i = 0; i < 6; i++)
printf("%.2f ", b[i]); //32.51 63.36 5.90 95.60 0.00 0.00
char c[5]; //整型、实型、字符型数组整体不赋初值
for(i=0; i<6; i++)
printf("%c ", c[i]);
//int:-858993460 -858993460 -858993460 -858993460 -858993460
//float:-107374176.000000 -107374176.000000 -107374176.000000 -107374176.000000 -107374176.000000
//char:??????
'\0'、0、NULL一样吗
以下是C语言他爹写的K&R2原文:
字符常量'\0'表示值为 0 的字符,也就是空字符(null)。我们通常用'\0'的形式代替 0,以强调某些表达式的字符属性,但其数字值为 0。
日常中,字符型用'\0',整型用0,实型用0.0,指针型用NULL
整型和字符型可以随意转换吗?
%c输出字符:
可以用字符原型、十进制、八进制、十进制的整数、或者八进制、十六进制的转义字符输出
例如:字符'A'的输出形式:
printf("%c",'A'); //A 字符原型输出
printf("%c,%c,%c\n",65,0101,0x41); //A,A,A 进制整数输出
printf("%c,%c,%c\n",65,'\101','\x41'); //A,A,A 转义字符输出
如果 0101不加0.那就不是八进制,而是十进制101,对应的字符是 e 。同理,0x41不加0x也不是十六进制,而是十进制41,对应的字符是 ) 。
printf("%c,%c,%c\n",65,101,41); //A,e,)
输出表列中的字符必须加单引号,否则报错。输出时不显示单引号
printf("%c",A); //报错 (这个A代表变量A,但是没定义变量A)
什么时候字符不用加单引号?
在scanf("%c",&a)里不用加,因为逗号左边的""内是格式控制字符串,字符串已经有双引号了,自然不用加单引号。
而printf("%c",a)里,当a作为变量时也不用加,因为输出时系统直接输出字符,不会输出双引号或单引号。而当a作为字符时,为了区别变量与字符串,则必须加单引号才能输出(否则会当变量使用,如果未定义变量则报错)
我们用单引号只是为了清楚地看出这是个字符,例如:a和a,哪个是字符?不知道。而a和'a'呢?显然是后者。
char a;
scanf("%c",&a); //输入:a (scanf输入时不用加单引号)
printf("%c\n",a); //输出:a (printf输出时也不会加单引号)
printf("%c\n",'a'); //输出:a
整型函数算是整型变量吗?
返回值是整型的函数,他们的返回值就是整型,是不是可以理解为函数也是整型的变量?
sqrt是一个double型的函数,他可以用在其他的实参内
- 点赞
- 收藏
- 关注作者
评论(0)