#include <stdio.h>
#include <conio.h>
#include <string.h>
typedef struct {
char serie_calculator[45];
char tip_procesor[78];
char memorie[55];
char hdd[60];
char monitor[65];
}Calculator;
void deleting(Calculator *ct, int *dim, char serie[45])
{
int k = 0, i, j;
for (i = 0;i<(*dim);i++)
if (strcmp((ct + i)->serie_calculator, serie) == 0)
{
k++;
for (j = i;j < (*dim - k);j++)
*(ct + j) = ct[j + 1]; // <== This line here
}
*dim = *dim - k;
}
在deleting
函数中,我不明白行*(ct + j) = ct[j + 1];
的作用。有人可以帮忙吗?我希望你理解这个功能,因为这只是整个程序的一个序列。
答案 0 :(得分:1)
在此功能中
void deleting(Calculator *ct, int *dim, char serie[45])
似乎第一个参数被声明为指向作为参数传递给函数的数组的第一个元素的指针。
因此
ct[0]
将表示数组的第一个元素
ct[1]
将表示数组的第二个元素,依此类推。
此记录
ct[i]
其中i是某个索引等同于
*( ct + i )
所以这句话
*(ct + j) = ct[j + 1];
也可以写成
ct[j] = ct[j + 1];
至于功能本身,那是完全错误的。
在这个循环中
for (j = i;j < (*dim - k);j++)
*(ct + j) = ct[j + 1]; // <== This line here
正如所说的那样也可以写成
for (j = i;j < (*dim - k);j++)
ct[j] = ct[j + 1]; // <== This line here
当j等于*dim - 1
时,尝试在数组之外写入,因为在这种情况下,表达式j + 1
将等于*dim
,尽管索引的有效范围是{{ 1}}
外环中的条件也应至少看起来像
[0, *dim - 1]
,删除数组的元素时,不应增加索引for (i = 0; i < (*dim) - k; i++)
^^^^^^^^^^^^^^
。否则,将跳过已删除元素之后的下一个元素。
我命名为i
的函数的正确实现可以采用以下方式,如下面的演示程序所示。我简化了结构声明,因为结构的其他数据成员与函数实现无关。
remove_all
程序输出
#include <stdio.h>
#include <string.h>
typedef struct
{
char serie_calculator[45];
// ...
} Calculator;
size_t remove_all( Calculator c[], size_t n, const char *s )
{
size_t i = 0;
for ( size_t j = 0; j < n; j++ )
{
if ( !( strcmp( c[j].serie_calculator, s ) == 0 ) )
{
if ( i != j ) c[i] = c[j];
++i;
}
}
return i;
}
int main(void)
{
Calculator c[] = { { "A" }, { "B" }, { "C" }, { "A" }, { "D" }, { "E" }, { "A" } };
const size_t N = sizeof( c ) / sizeof( *c );
for ( size_t i = 0; i < N; i++ ) printf( "%s ", c[i].serie_calculator );
printf( "\n" );
size_t n = remove_all( c, N, "A" );
for ( size_t i = 0; i < n; i++ ) printf( "%s ", c[i].serie_calculator );
printf( "\n" );
return 0;
}