ANSI C:如何对结构字段进行抽象?
ANSI C : How do I abstract over over struct fields?
我有一个表示为 RGB 像素二维数组的图像。
typedef struct {
char R;
char G;
char B;
} RGB;
以及为该图像的每个像素计算新颜色的函数:
RGB new_color(RGB image[][], int r, int c){
RGB color;
color.R = image[r][c].R + image[r+1][c].R + image[r-1][c].R + image[r][c+1].R + image[r][c-1].R;
color.G = image[r][c].G + image[r+1][c].G + image[r-1][c].G + image[r][c+1].G + image[r][c-1].G;
color.B = image[r][c].B + image[r+1][c].B + image[r-1][c].B + image[r][c+1].B + image[r][c-1].B;
return color;
}
是否可以删除 new_color 正文中的重复代码?换句话说抽象了 RGB 数据结构的字段名称?
让我们暂时忽略 RGB image[][]
在 C89 中是不合法的。
您可以提取访问函数。
char *get_RGB_R(RGB* rgb) { return &rgb->R; }
char *get_RGB_G(RGB* rgb) { return &rgb->G; }
char *get_RGB_B(RGB* rgb) { return &rgb->B; }
然后编写一个使用它们的辅助函数。
void set_color_channel_from_adjacent(
char *(*accessor)(RGB*), RGB* result, RGB image[][], int r, int c)
{
*accessor(result) = *accessor(&image[r][c]) +
*accessor(&image[r+1][c]) +
*accessor(&image[r-1][c]) +
*accessor(&image[r][c+1]) +
*accessor(&image[r][c-1]);
}
然后调用辅助函数
RGB new_color(RGB image[][], int r, int c)
{
RGB color;
set_color_channel_from_adjacent(get_RGB_R, &color, image, r, c);
set_color_channel_from_adjacent(get_RGB_G, &color, image, r, c);
set_color_channel_from_adjacent(get_RGB_B, &color, image, r, c);
return color;
}
现代编译器将内联短函数并生成与原始代码等效的代码。
我有一个表示为 RGB 像素二维数组的图像。
typedef struct {
char R;
char G;
char B;
} RGB;
以及为该图像的每个像素计算新颜色的函数:
RGB new_color(RGB image[][], int r, int c){
RGB color;
color.R = image[r][c].R + image[r+1][c].R + image[r-1][c].R + image[r][c+1].R + image[r][c-1].R;
color.G = image[r][c].G + image[r+1][c].G + image[r-1][c].G + image[r][c+1].G + image[r][c-1].G;
color.B = image[r][c].B + image[r+1][c].B + image[r-1][c].B + image[r][c+1].B + image[r][c-1].B;
return color;
}
是否可以删除 new_color 正文中的重复代码?换句话说抽象了 RGB 数据结构的字段名称?
让我们暂时忽略 RGB image[][]
在 C89 中是不合法的。
您可以提取访问函数。
char *get_RGB_R(RGB* rgb) { return &rgb->R; }
char *get_RGB_G(RGB* rgb) { return &rgb->G; }
char *get_RGB_B(RGB* rgb) { return &rgb->B; }
然后编写一个使用它们的辅助函数。
void set_color_channel_from_adjacent(
char *(*accessor)(RGB*), RGB* result, RGB image[][], int r, int c)
{
*accessor(result) = *accessor(&image[r][c]) +
*accessor(&image[r+1][c]) +
*accessor(&image[r-1][c]) +
*accessor(&image[r][c+1]) +
*accessor(&image[r][c-1]);
}
然后调用辅助函数
RGB new_color(RGB image[][], int r, int c)
{
RGB color;
set_color_channel_from_adjacent(get_RGB_R, &color, image, r, c);
set_color_channel_from_adjacent(get_RGB_G, &color, image, r, c);
set_color_channel_from_adjacent(get_RGB_B, &color, image, r, c);
return color;
}
现代编译器将内联短函数并生成与原始代码等效的代码。