此程序要求用户填写表格并询问他要删除的值,然后创建没有值的新表
#include<stdio.h>
#include<stdlib.h>
main()
{
int *tab;
int *p1,*p2;
int nb,val,i;
printf("Number of values for the table ? ");
scanf("%d",&nb);
tab=(int*)malloc(nb*sizeof(int)); // on alloue le nombre de cases demandees au tableau
for (i=0;i<nb;i++)
{
printf("value n %d of the table? ",i);
scanf("%d",&tab[i]);
}
printf("\n value to delete of the table ? ");
scanf("%d",&val);
p1=tab; // on fait pointer p1 s ur la premiere case du tableau
p2=tab; // idem pour p2
// p1 va parcourir le tableau tout entier
// p2 n'avancera que si l'element du tableau en cours est different de val
while (p1<tab+nb) // tant qu'on n'est pas a la fin du tableau
{
if (*p1!=val) // si l'element en cours est different de val
{
*p2=*p1; // on recopie l'element dans la case pointee par p2
p2++; // on incremente p2 pour passer a la case suivante
}
p1++;
}
for (i=0;i<*p2-*tab;i++) // p2-tab= nombre de cases encore remplies
{
printf("value n %d of the table : %d\n",i,tab[i]);
}
}
我不明白为什么最后一个for循环也可以这样写?
for (i=0;i<p2-tab;i++)
它不应该返回地址的值,只返回地址
答案 0 :(得分:2)
for (i=0;i<*p2-*tab;i++)
暴露undefined behaviour,无论如何它在语义上都是错误的。
正确的代码是:
for (i=0;i<p2-tab;i++)
{
printf("value n %d of the table : %d\n",i,tab[i]);
}
i
用作tab
(tab[i]
)中的索引,p2
指向元素等于{后的数组的最后一个元素之后的第一个元素{1}}被删除了。
val
是删除后数组中元素的数量,这是为了打印剩余数字而执行的正确迭代次数。
p2-tab
错了?从语义的角度来看,for (i=0;i<*p2-*tab;i++)
和*p2
是数组中的两个元素(忽略*tab
超出数组边界的情况,我们将讨论它两个以下段落。
因此,*p2
是一些随机数,甚至可能是负数。将它用作数组上的迭代次数没有任何意义。
从语言的角度来看,如果数组的初始内容中不存在*p2-*tab
,则在“删除”后,val
等于p2
。但是tab+nb
指向一个分配的内存块,它可以容纳最多tab
个值,这意味着nb
在这个内存块之外。
这使得代码具有undefined behaviour,这意味着任何事情都可能发生;有时它运行得很好;大多数时候它会产生意想不到的结果;根据操作系统和编译器的实现,它还可以生成未处理的异常,并由操作系统终止。