大家好我有一个问题,
我有一个包含10个元素的数组和一个函数,它返回一个指向数组中随机选择元素的指针。现在我想从指针指向的元素打印数组,我该怎么做。
实施例: 阵列:1,2,3,4,5,6,7,8,9,10 指针指向元素6。 我想打印:6,7,8,9,10
代码在C中显示如下:
int* randomElement(int* array, int size) {
int* pointer = NULL;
int randomNumber = 0;
randomNumber = rand() % size;
*pointer = *(array + randomNumber);
return pointer;
}
int main(void) {
int size = 10;
int array[size];
int* pointer = NULL;
srand(time(NULL));
pointer = randomElement(array, size);
/* Want to print the array from this element here */
return EXIT_SUCCESS;
}
答案 0 :(得分:2)
你不能。
通过仅知道数组中的随机元素(即具有指向一个元素的指针),您无法使用该指针打印整个数组。
您至少还需要两个其他数据:
1)数组的长度(你似乎总是表示10)。
2)数组中具有指针的元素的位置。这样您就可以从该位置计算出前后可用的元素数量。 (基本上确定数组边界)。
编辑后,答案保持不变。但是你的代码存在问题:
1)您没有使用值填充数组。因此,他们的值不确定并且认为它们是undefined behaviour。
2)您从未将pointer
设置为指向randomElement()
中数组的元素,函数返回NULL
。你解除引用NULL(pointer
)。同样,这将导致未定义的行为。
3)您应该使用size_t
代表数组大小而不是int
。
答案 1 :(得分:1)
我不会评论你的代码,已经完成了。我会改回原来的问题。蓝月亮说“你不能”,但如果你愿意,你可以。如果您的值列表以所谓的 sentinel 值终止,则您始终可以在任何表中执行顺序查找。这是一个特殊值,它事先已知不属于正常数据的集合,因此可用于标记序列的结尾,例如,如果已知所有正常数据都是正数,则为负值。
对于存储在n
元素数组中的n+1
非负整数序列,我们可以在填充第一个array[n]= -1
元素后将n
存储为哨兵正常数据。然后从数据序列中的随机位置开始,一直读到最后,如
// -- we assume pointer p is an initialized int* that
// satisfies the condition array <= p < array + n
// AND that array[n] is negative.
for( ; *p >= 0; ++p ){
// do something useful with *p
}
使用哨兵终止序列是一种众所周知的通用技术,您可以在任何关于算法的书籍中找到它。您可以将它与数组和链接列表一起使用。在您的情况下,您必须确保要在数组中访问的最后一个元素后面的元素是一个哨兵,并且随机选择没有选择哨兵(如果n
是序列的长度,然后rand() % n
将给你一个正确的偏移;指向一个标记不会伤害,但for
循环将立即终止)。分配的数组的大小必须至少 n+1
,这是您需要的最大数据元素数,加上前哨数的一个。
顺便说一下,在C中,数组的最后一个元素不是array[size]
而是array[size-1]
。在C中碰撞指针时,没有对数组访问的边界检查,这取决于你,因为你迟早会从崩溃的程序中学习。为了消除指针和引用值之间的混淆,您可以阅读“如果不是内存地址究竟是什么C指针?”,Stackoverflow上的here的指导性答案。
答案 2 :(得分:0)
使用指针迭代数组的常用方法是:
for (p = array; p != array + size; ++p)
在您的情况下,您正在以不同方式初始化p
,但循环的其余部分可以保持不变:
for ( ; pointer != array + size; ++pointer )
{
printf("%d\n", *pointer);
}
当然也可以使用整数索引而不是指针(通过pointer - array
找到初始索引)。
请注意,您的randomElement
功能目前是错误的。它通过空指针写入。相反,您要做的是形成一个指向随机选择元素的指针并返回该指针,而不进行解除引用。 (即在*
之前将return
排除在外。