题目描述
在C/C++/Java等编程语言中,int类型的变量通常占4个字节的大小,在按字节编址的系统中,给定一个长度为N的数组的首地址(16进制)。
小蓝会进行多次的地址询问(16进制),你需要回答出这个地址实际所指的数组下标(从O开始)。若访问的数据内存地址不在数组范围内,输出-1。你无需考虑指向非单个数据首地址的情况,你只需要回答出地址所在的数据的下标。
输入
第一行输入两个正整数N,Q和一个十六进制数X,分别表示数组长度,询问次数和数组首地址。接下来Q行,每行输入一个十六进制数a,表示第i次询问的地址。
*十六进制字母部分为小写。
输出
输出Q行,每行一个整数αi,第i行输出的整数表示第i次询问的结果。
源代码
下面是一个C语言的程序示例,可以根据给定的数组长度、首地址和询问地址,输出对应的数组下标:
#include <stdio.h>
int main() {
int N, Q;
unsigned int X;
scanf("%d %d %x", &N, &Q, &X); // 输入数组长度、询问次数和数组首地址
int* arr = (int*)X; // 将首地址强制转换为int指针类型
for (int i = 0; i < Q; i++) {
unsigned int a;
scanf("%x", &a); // 输入询问地址
if (a >= X && a < X + N * sizeof(int)) {
int index = (a - X) / sizeof(int); // 计算数组下标
printf("%d\n", index);
} else {
printf("-1\n"); // 地址不在数组范围内
}
}
return 0;
}
在这个程序中,我们首先使用scanf
函数输入数组长度、询问次数和数组首地址。注意,这里我们使用了unsigned int
类型来接收地址,以确保能够正确处理16进制的输入。
接下来,我们将给定的数组首地址强制转换为int
指针类型,并将其赋值给指针变量arr
。这样,arr
就指向了给定的数组。
然后,我们使用一个循环来处理每次询问。在每次循环中,我们使用scanf
函数输入询问地址,并判断该地址是否在数组范围内。如果地址在数组范围内,我们可以通过计算地址与数组首地址之间的偏移量来得到对应的数组下标。具体地,我们将地址减去数组首地址,并除以sizeof(int)
来得到偏移量,然后将其赋值给变量index
。最后,我们输出index
作为结果。如果地址不在数组范围内,我们直接输出-1。
需要注意的是,在实际应用中,需要进行输入验证以确保程序的正确性,例如判断输入的数组长度、询问次数和地址是否合法,以及判断数组是否越界等。