1.下面代码的结果是:( )
#include <stdio.h>
int main()
{
int i = 1;
int ret = (++i) + (++i) + (++i);
printf("ret = %d\n", ret);
return 0;
}
A.10
B.12
C.9
D.程序错误
答案解析:
答案是:D
如果你在VS上运行了这段代码,运行结果是12,你就选择了B,但是这样就错了,在不同的编译器它可能有着不同的运行结果。因为这个表达式的求值顺序是不确定的,第一个+和第三个++的不知谁先谁后,不能通过操作符的属性确定唯一的计算路径,那这个表达式就是存在问题的。
知识点:
1.表达式求值
表达式求值的顺序是由操作符的优先级和结合性决定的,但注意,有些表达式的操作数再求值的过程中可能需要转换为其他类型。
1.1 类型转换
低于int型的char,short为整形提升,等于或大于int型的为算术转换(从低到高)。
1.2 操作符的属性
①首先确定优先级,相邻操作符按照操作符优先级高级计算(相邻操作符才讨论优先级)
②优先级相同的情况下,结合性才起作用。
③注意操作符是否控制求值顺序(只有四个:&& || (?:) ,)
1.3 总结
我们写出的表达式如果不能通过操作符的属性确定唯一的计算途径,那这个表达式就是存在问题的。
1.4 补充:
(1)操作符的优先级:
()(聚组>函数调用) > [](下标引用)> 访问结构体成员操作符(. ->)> 后缀++ --
> 单目操作符(! ~ + - ++ -- * & sizeof (类型) )> 算术操作符(* / % + -)>移位操作符(<< >>) > 关系操作符(> >= < <= == !=)> 位操作符(& | ^)> 逻辑操作符(&& ||)> 条件操作符 > 赋值操作符 > 逗号操作符
(2)操作符的结合性
单目操作符和赋值操作符是自右向左结合,其余一般都是自左向右。
2.下面代码的结果是:
#include <stdio.h>
int i;
int main()
{
i--;
if (i > sizeof(i))
{
printf(">\n");
}
else
{
printf("<\n");
}
return 0;
}
A.>
B.<
C.不输出
D.程序有问题
答案解析:
答案是:A
详细图解:
3.关于表达式求值说法不正确的是:( )
A.表达式求值先看是否存在整形提升或算术转换,再进行计算
B.表达式真正计算的时候先看相邻操作符的优先级决定先算谁
C.相邻操作符的优先级相同的情况下,看操作符的结合性决定计算顺序
D.只要有了优先级和结合性,表达式就能求出唯一值
答案解析:
答案是:D
如例题1,有了操作符的优先级和结合性,但是还是不能确定表达式的唯一计算途径。
4.点击下方链接
代码1:
分析:使用数组存放矩阵元素,同时统计大于0的元素。
#include <stdio.h>
int main()
{
//行
int n=0;
//列
int m=0;
int arr[10][10]={0};
int sum=0;
//输入行和列,且<=10
scanf("%d %d",&n,&m);
//行循环变量
int i=0;
for(i=0;i<n;i++)
{
//列循环变量
int j=0;
for(j=0;j<m;j++)
{
//输入矩阵元素
scanf("%d",&arr[i][j]);
//输入数据的同时,统计大于0的元素之和
if(arr[i][j]>0)
{
sum+=arr[i][j];
}
}
}
//输出
printf("%d\n",sum);
return 0;
}
代码2:
分析:其实题目只是统计矩阵大于0的元素,所以没必要把数组元素存储起来,使用变量tmp接收并判断即可。
//没必要把数组元素存起来,使用变量tmp接收数组元素即可
#include<stdio.h>
int main()
{
int n = 0;
int m = 0;
scanf("%d %d", &n, &m);
int i = 0;
int j = 0;
int tmp = 0;
int sum = 0;
for (i = 0; i < n; i++)
{
for (j = 0; j < m; j++)
{
scanf("%d", &tmp);
if (tmp > 0)
{
sum += tmp;
}
}
}
printf("%d\n", sum);
return 0;
}
代码3:
分析:牛客网支持变长数组的特性,所以也可使用变长数组来存储矩阵的元素。
知识点:
①牛客可以使用变长数组;
②使用变长数组,注意不能初始化。
#include<stdio.h>
int main()
{
int n = 0;
int m = 0;
scanf("%d %d", &n, &m);
//变长数组,因为牛客网的oj是支持C99标准的,所以可以使用
int arr[n][m];
int i = 0;
int j = 0;
int sum = 0;
for (i = 0; i < n; i++)
{
for (j = 0; j < m; j++)
{
scanf("%d", &arr[i][j]);
if (arr[i][j] > 0)
{
sum += arr[i][j];
}
}
}
printf("%d\n", sum);
return 0;
}
5.点击链接做题
代码1:数组存放
分析:进制转化整数部分——取余倒排序法
//正序打印——数组存放
#include<stdio.h>
int main()
{
int n = 0;
//输入n
scanf("%d", &n);
//计算得到n表示六进制的逆序结果——数组存放
int arr[20] = { 0 };
int i = 1;
while (n)
{
arr[i] = n % 6;
n /= 6;
i++;
}
//打印n六进制的结果
while (--i)
{
printf("%d", arr[i]);
}
printf("\n");
return 0;
}
代码2:递归
//递归
#include <stdio.h>
void print(int n)
{
if (n > 5)
{
print(n / 6);
}
printf("%d", n % 6);
}
int main()
{
unsigned int n = 0;
while ((scanf("%d", &n)) != EOF)
{
print(n);
printf("\n");
}
return 0;
}
6.点击链接做题
//矩阵转置——只是打印的方式不同
#include <stdio.h>
int main()
{
int n = 0;
int m = 0;
scanf("%d %d", &n, &m);
int arr[n][m];
int i = 0;
int j = 0;
for (i = 0; i < n; i++)
{
for (j = 0; j < m; j++)
{
scanf("%d ", &arr[i][j]);
}
}
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
printf("%d ", arr[j][i]);
}
printf("\n");
}
return 0;
}
7.点击链接做题
代码1:投机取巧1
分析:投机取巧1——并没有真正删除,只是将要删除的数改成0,不打印0。
//投机取巧1——并不真正删除
#include <stdio.h>
int main()
{
int n = 0;
scanf("%d", &n);
int arr[n];
int i = 0;
for (i = 0; i < n; i++)
{
scanf("%d", &arr[i]);
}
//输入要删除的数
int del = 0;
scanf("%d", &del);
for (i = 0; i < n; i++)
{
if (arr[i] == del)
{
arr[i] = 0;
}
}
//输出
for (i = 0; i < n; i++)
{
if (arr[i] != 0)
{
printf("%d ", arr[i]);
}
}
return 0;
}
代码2:投机取巧2
分析:既然代码1可以,那我们直接在打印时判断,不等于删除的数才打印。
//投机取巧2
#include<stdio.h>
int main()
{
int n = 0;
scanf("%d", &n);
int arr[n];
int i = 0;
for (i = 0; i < n; i++)
{
scanf("%d", &arr[i]);
}
//输入删除的数,直接判断不相等就输出
int del = 0;
scanf("%d", &del);
for (i = 0; i < n; i++)
{
if (del != arr[i])
{
printf("%d ", arr[i]);
}
}
return 0;
}
代码3:真正的删除
分析:删除——>数组要实现删除的话,使用后面的元素将其覆盖即可。
图解
//真正将数组中要删除的数据删除掉
#include<stdio.h>
int main()
{
int n=0;
scanf("%d",&n);
int arr[n];
int i=0;
for(i=0;i<n;i++)
{
scanf("%d",&arr[i]);
}
//输入想要删除的数
int del=0;
scanf("%d",&del);
//删除
int j=0;//作为下标锁定的位置就是用来存放不删除的数据的
for(i=0;i<n;i++)
{
if(arr[i]!=del)
{
arr[j++]=arr[i];
}
}
//输出删除后的数组
for(i=0;i<j;i++)
{
printf("%d ",arr[i]);
}
return 0;
}