不同类型的值传递
// 下列程序的输出结果是
long a1 = 0xffff;
int b1 = a1;
printf("%d",b1);
/*
* a1为长整型,在微型机中占4个字节,由于每个字节等于8位
* 所以a1的存储占4*8=32位,其中后16位全是1,其余都是0
* b1为int类型,在微型机中占2个字节,所以存储中占16位且全部是1
*
* 当把a1的值赋值给b1时,高16位上的值被自动截断,只保留低16位上的值
* 由于输出占位符是%d,所以按10进制输出
* 输出结果是-1
*/
写一个随机口算题卡生成测试并计算总分
按照出现次数进行排序
class OutputByOccurrence {
private static int[]
mainProcess(int arrs[]) {
Set<Map.Entry<Integer, Integer>> set = new TreeSet<>(new ManualComparator());
Map<Integer, Integer> map = new TreeMap<>();
addElementToCollection(arrs, map, set);
return setToArr(map, set);
}
private static void
addElementToCollection(int[] arrs, Map<Integer, Integer> map, Set<Map.Entry<Integer, Integer>> set) {
for (int i : arrs) {
map.put(i, map.containsKey(i) ? map.get(i) + 1 : 1);
}
for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
set.add(entry);
}
}
private static int[] setToArr(Map<Integer, Integer> map, Set<Map.Entry<Integer, Integer>> set) {
int[] newArrs = new int[map.size()];
List<Map.Entry<Integer, Integer>> list = new ArrayList<>(set);
for (int i = 0; i < newArrs.length; i++) {
newArrs[i] = list.get(i).getKey();
}
return newArrs;
}
public static void
main(String[] args) {
int[] arr = {1, 3, 2, 7, 2, 6, 7, 1, 1, 1, 1};
System.out.println(Arrays.toString(mainProcess(arr)));
}
}
/**
* 自定义比较器
*
* @apiNote 功能实现核心类
* 比较规则按数字出现的次数从小到大进行输出
*/
class ManualComparator implements Comparator {
@Override
public int compare(Object o1, Object o2) {
Map.Entry<Integer, Integer> key_value_01 = (Map.Entry<Integer, Integer>) o1;
Map.Entry<Integer, Integer> key_value_02 = (Map.Entry<Integer, Integer>) o2;
int num = key_value_01.getValue() - key_value_02.getValue();
if (num == 0) {
return key_value_01.getKey() - key_value_02.getKey();
}
return num;
}
}
空指针操作
int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12},
*p = a + 5, *q = NULL;
*q = *(p+5);
printf("%d %d\n", *p, *q);
/*
* 编译器会报错
* CLion会卡住不往下执行
* *p = a + 5 表示把数组的第6个元素的地址赋值给p
* *q = *(p + 5) 表示把数组第11个内容赋值给*q
* 但在此之前*q已经被赋值NULL
* 说明q是1个空指针
* 对空指针操作会导致程序崩溃
*/
32位操作系统存储细节
struct Demo1{
char a;
float b;
short c;
char d;
};
// 在32位机器上,结构体sizeof的结果是
// 16
// 8
// 12
// 10
// 正确答案:C
// 注意:struct的sizeof受排序顺序的影响,因为当前类型存储是否需要开辟存储空间不仅取决于自己是什么类型,还取决于下面一行代码的数据类型
数组下表越界与类型比较风险
float f[10];
// 假设这里有对f进行初始化的代码
// ….
for(int i = 0; i < 10;) {
if(f[++i] == 0)
break;
}
// 指出下列代码的缺陷
/*
* for(int i = 0; i < 10;)这一行写错了
* f是float型数据直接做相等判断有风险
* f[++i]应该是f[i++]
* 没有缺陷
*/
// 正确答案:BC
/*
* 如果数组中的某个值是0,那么浮点型的0不是真正的0,
* 而是类似0.00000001这样的近似数
* 这样的值跟0比较的话是不相等的
* 也就是说0!=0也就不会break退出循环
* 建议浮点值用包装类的equals方法判断
*/
/*
* C语言没有数组越界检查
* f[++i]直接指向索引到第2个元素
* 直接跳过了第1个元素
*/
C链表节点连接
/*
* p是一指向结构体类型的指针变量,其初始值是让其指向结构体变量a,要通
* 过指针变量p来引用结构体变量的成员next,通常可使用两种形式:p->next 或(*p).next
* 就是本题的CD选项
* 而p.next是非法的引用
*/
指针变量指向同一个变量
/*
* 先不看指针,假设有一个int a;
* int *b = &a;
* 是a地址,也就是指针
* *b ;
* 那就是得到a的值,等同于a。
* 那么两句话合二为一就是
* *(&a)等价于a
*
* 所以 p2 = *&p1 等价于 p2 = p1
* 所以p1 ,p2指向了同一个东西
*/