C语言 如何从一段完整的代码中提取函数?

rsl1atfo  于 2022-12-17  发布在  其他
关注(0)|答案(1)|浏览(325)

据说创建许多小函数比创建几个大函数要好。因此,如果一个函数变得太大,人们可能希望将它的一部分提取到一个单独的函数中。但技术上如何做到这一点?函数之间交换数据的方法有很多,何时使用每一种方法?

utugiqy6

utugiqy61#

人们需要遵循的简单机械规则很少。
1.有新函数需要使用但不需要修改的数据吗?by value or by pointer to const.(大多数人会告诉你,在C语言中所有东西都是传值的,没有传指针这种东西,我只是为了方便才编了这个词,传指针X和传指针给X是一样的)。例:查找数组中的最大值。

  • 之前:
int array[MAX_ARRAY];
size_t actual_size;
// array initialised here
...
// want to extract this piece of code
// the function needs to look at the array and the size,
// but not change them
int maxVal = array[0];
for (int i = 1; i < actual_size; ++i) {
  if (array[i] > maxVal) maxVal = array[i];
}
  • 之后:
// Passing the array by const pointer (cannot pass arrays by value)
// and size by value
// In case of arrays we pass a pointer to the first element, rather than
// a pointer to the array itself.
int findMax(const int* array, size_t size) {
  int maxVal = array[0];
  for (int i = 1; i < actual_size; ++i) {
    if (array[i] > maxVal) maxVal = array[i];
  }
  return maxVal;
}
...
// An array decays to a pointer to its first element
int maxVal = findMax(array, actual_size);

这里我们有两个东西要传递给函数:数组和数组大小。数组通过指向const* 的指针传递(不能通过值传递数组),大小通过值传递。如果您可以选择通过值传递或通过const指针传递,这意味着您有structunion,如果值相当小(几个整数或指针),请选择通过值传递。否则通过指向const的指针传递。
1.有一小段数据需要新函数初始化/创建/计算吗?* 返回 * 它从函数。上面的例子也说明了从函数返回。下面是另一个返回值的例子:

  • 之前:
size_t array_size;
// Want to extract this piece of code
// 'array' should be initialised inside, and used outside afterwards
int* array = malloc(array_size * sizeof(*array));
for (size_t i = 0; i < array_size; i++)
  array[i] = rand();
  • 之后:
// Make 'array' the return value of the function
int* create_random_array(size_t array_size) {
  int* array = malloc(array_size * sizeof(*array));
  for (size_t i = 0; i < array_size; i++)
    array[i] = rand();
  return array;
}
...
int* array = create_random_array(array_size);

/* INCORRECT, won't work, never do this */ 
void create_random_array(int* array, size_t array_size) {
  array = malloc(array_size * sizeof(*array));
...
int* array;
create_random_array (array, array_size);

1.有一段数据需要函数在修改之前查看吗?有一大段数据需要函数初始化吗?有几段小数据需要函数初始化吗?在每种情况下,都要通过指针传递(指向非常量)。例如:将节点插入链表。

  • 之前:
Node* head = NULL;
// maybe insert a few elements
...
// want to extract this piece of code
// head is initialised above, may be changed in the function,
// and then used after the call
Node* new_node = malloc(sizeof(*new_node));
new_node->data = data;
new_node->next = head;
head = new_node;
  • 之后:
// Passing the head of the list by pointer, even though
// it is a pointer itself. This results in a pointer-to-pointer
// and two stars in the declaration of pNode
void insertFront(node** pHead, int data) {
  Node* new_node = malloc(sizeof(*new_node));
  new_node->data = data;
  new_node->next = *pHead;
  *pHead = new_node;
}
...
insertFront(&head, data);

// Variant that uses a combination of techniques above instead
// Pass old head by value, return new head
// The same technique is used by e.g. realloc: old pointer by value,
// return new pointer. If your function wraps realloc and adds 
// a few bells and whistles, consider using this technique
node* insertFront(node* head, int data) {
  Node* new_node = malloc(sizeof(*new_node));
  new_node->data = data;
  new_node->next = head;
  head = new_node;
  return head;
}
...
head = insertFront(head, data);

/* INCORRECT, won't work, never do this */ 
void insertFront(node* head, int data) { ...

另一个例子:找出数组中的最大值和最小值。

  • 之前:
int array[MAX_SIZE];
size_t actual_size;
// array and actual_size initialised here
...
// Want to extract this piece of code
// Both maxVal and minVal are initialised inside
// and need to be used outside afterwards
int maxVal = array[0], minVal = array[0];
for (size_t i = 1; i < actual_size; i++) {
   if (array[i] > maxVal) maxVal = array[i];
   else if (array[i] < minVal) minVal = array[i];
}
  • 之后:
// Min and max values are passed by pointer
// They are so-called output parameters
void findMinMax(const int* array, size_t size, int* pMaxVal, int* pMinVal) {
  *pMaxVal = array[0];
  *pMinVal = array[0];
  for (size_t i = 1; i < actual_size; i++) {
    if (array[i] > *pMaxVal) *pMaxVal = array[i];
    else if (array[i] < *pMinVal) *pMinVal = array[i];
  }
}
...
int maxVal, minVal;
findMinMax(array, actual_size, &maxVal, &minVal);

1.最后,还有一种通过使用全局/静态变量在函数之间传递数据的技术,不要使用它。

相关问题