roll()函数导致的未定义行为(使用C)
我想要一个程序,从用户那里获取一个元素数组,并以不同的顺序输出数组,其中roll()函数导致的未定义行为(使用C),c,arrays,undefined-behavior,pointer-arithmetic,C,Arrays,Undefined Behavior,Pointer Arithmetic,我想要一个程序,从用户那里获取一个元素数组,并以不同的顺序输出数组,其中3rd元素取代1st,而1st和2nd元素向下移动1元素位置。 以下是预期的输入/输出: Enter the array length: 7 Enter the elements in the array: 5 3 4 9 8 7 2 然后,数组a2的输出应为: The output array is: 4 5 3 9 8 7 2 但是,当我编译并运行源代码时,我会将其作为输出: 25 0 -617353404 32
3rd
元素取代1st
,而1st
和2nd
元素向下移动1
元素位置。
以下是预期的输入/输出:
Enter the array length: 7
Enter the elements in the array: 5 3 4 9 8 7 2
然后,数组a2
的输出应为:
The output array is: 4 5 3 9 8 7 2
但是,当我编译并运行源代码时,我会将其作为输出:
25 0 -617353404 32766 4196318 0 -1
现在我知道它与导致未定义行为的roll()
函数有关。但是,我不确定必须在roll()
函数中更改什么才能阻止这种情况发生
还请记住,我可能只在roll()
函数中使用指针算法(基本上可以)
接下来我应该做什么来确保我的代码在使用指针算法的同时准确修改a2
数组,以便它在主函数中正确打印a2
数组中的值
以下是我的源代码:
#include <stdio.h>
void roll(int *a1, int n, int *a2);
int main()
{
int s, i;
printf("Enter the size of array: ");
scanf("%d", &s);
int a1[s], a2[s];
printf("Enter the elements of the array: ");
for(i = 0; i < s; i++)
{
scanf("%d", &a1[i]);
}
a2[s] = a1[s];
roll(a1, s, a2);
for(i = 0; i < s; i++)
{
printf("%d ", a2[i]);
}
return 0;
}
void roll(int *a1, int n, int *a2)
{
int *p, *q;
int *r, *s, *t;
int *u, *v, *w;
p = a1 + n;
q = a2 + n;
r = a1;
s = a1 + 1;
t = s + 1;
u = a2;
v = a2 + 1;
w = v + 1;
u = t;
v = r;
w = s;
}
#包括
无效滚动(int*a1、int*n、int*a2);
int main()
{
int s,i;
printf(“输入数组的大小:”);
scanf(“%d”和“&s”);
int a1[s],a2[s];
printf(“输入数组的元素:”);
对于(i=0;i
谢谢。看来你不知道该怎么办。例如,不需要分配:
a2[s] = a1[s];
更麻烦的是,您正在调用未定义的行为来超越数组边界
您的roll
功能没有做任何有用的事情。
您需要遵从指针来实际访问数组的元素
解决方案比您想象的简单。首先处理数组的3
元素a1
,然后将数组的其余a1
复制到数组a2
还请记住,我可能只在
roll()
功能
当然可以,但是数组[]
操作符更好,memcpy
可能更快
测试程序:
#include <stdio.h>
void roll1(int *a1, int n, int *a2);
int main(void)
{
int s, i;
printf("Enter the size of array: ");
scanf("%d", &s);
int a1[s], a2[s];
printf("Enter the elements of the array: ");
for(i = 0; i < s; i++)
{
scanf("%d", &a1[i]);
}
roll1(a1, s, a2);
for(i = 0; i < s; i++)
{
printf("%d ", a2[i]);
}
return 0;
}
// 5 3 4 9 8 7 2
// 4 5 3 9 8 7 2
void roll1(int *a1, int n, int *a2)
{
// array subscription:
// 1.
//a2[0] = a1[2];
//a2[1] = a1[0];
//a2[2] = a1[1];
// or pointer arithmetic:
// 2.
//(*a2) = *(a1+2);
//*(a2+1) = *(a1);
//*(a2+2) = *(a1+1);
// 3. OR
int * a1p = a1;
int * a2p = a2;
int a2_0 = *a1;
int a2_1 = *(++a1p);
int a2_2 = *(++a1p);
//printf("%d %d %d\n",a2_0,a2_1,a2_2);
*(a2p) = a2_2;
++a2p;
*(a2p) = a2_0;
++a2p;
*(a2p) = a2_1;
// now the rest:
//1.
// memcpy(a2+3, a1+3, sizeof(int) * (n-3) );
//2. or
//for(int i=3; i<n; i++){
// *(a2+i) = *(a1+i);
//}
//3. OR
for(int i=3; i<n; i++){
*(++a2p) = *(++a1p);
}
}
a2
的唯一初始化是a2[s]=a1[s]
,它使用超出范围的索引s
。您从未初始化a2
的实际内容。至于roll
函数,它应该做什么?现在它实际上什么也没做。它是要改变a1中数组元素的顺序,然后修改a1就是数组a2。a1的第三个元素在数组中占据第一个位置,然后在第二和第三个位置填充第一和第二个元素。这个修改后的数组将是a2。对于初始化,我试图让数组a2具有分配给a1的相同用户输入元素。关于roll
函数。那不是你在做的。你要做的就是分配很多指针。你从来没有真正“滚动”过任何东西。“滚动”是指保存一个元素,然后保存其余元素,并将保存的元素恢复到新位置。我运行了这段代码,它工作得很好,只是在roll函数的for循环中没有使用指针算法。我现在意识到我没有指定,但是for循环应该只使用指针算法,而不使用I的索引。你可能有这样一个例子吗?@mannydezus:没问题:)。该示例已更新。
Enter the size of array: 7
Enter the elements of the array: 5 3 4 9 8 7 2
4 5 3 9 8 7 2