C Language interface and implementation method examples _c language

Source: Internet
Author: User
Tags assert

In this paper, the C language interface and implementation method are described in detail, which can be used for reference in the deep mastery of C language programming. Share to everyone for your reference. The specific analysis is as follows:

In general, a module consists of two parts: interface and implementation. interface indicates what the module is going to do, it declares the identifiers, types, and routines that are available to the code that uses the module to specify how the module completes its interface declaration goal , a given module usually has only one interface, but there may be many implementations that can provide the functionality specified by the interface. Each implementation may use different algorithms and data structures, but they must conform to the usage instructions given by the interface. A client invoker is a piece of code that uses a module that the client invokes to import an interface and implements the export interface . Because multiple client callers are shared interfaces and implementations, using the target code of the implementation avoids unnecessary code duplication and helps avoid errors because interfaces and implementations can be used more than once in writing and debugging.

Interface

An interface needs only to indicate the identifiers that a client caller might use, hiding extraneous presentation details and algorithms as much as possible , so that the client invoker does not have to rely on specific implementation details. This dependency between the client invoker and the implementation-coupled ----may cause errors when implementation changes, which can be difficult to fix when the dependency is buried in some of the hidden or ambiguous assumptions about the implementation An interface that is well designed and described accurately should minimize coupling .

C language provides the most basic support for the separation of interfaces and implementations, but simple conventions can bring significant benefits to the interface/implementation methodology. In C, the interface is declared in the header file, which declares the macros, types, data structures, variables, and routines that the client invoker can use. The user uses the C language preprocessing directive #include to import the interface .

The following examples illustrate some of the conventions and interfaces used in the interface of this article:

extern int Arith_max (int x, int y);
extern int arith_min (int x, int y);
extern int Arith_div (int x, int y);
extern int Arith_mod (int x, int y);
extern int arith_ceiling (int x, int y);
extern int Arith_floor (int x, int y);

The name of the interface is Arith, and the oral file is appropriately named Arith.h, and the name of the prefix of the interface appears in each identifier of the interface. The module name not only provides the appropriate prefix, but also helps to organize the client's calling program code.

The Arith interface also provides a number of functions that are not yet useful in the standard C function library, and provides a good definition for starting and fetching, while standard C does not define these operations and provides only implementation-based definitions.

Realize

An implementation exports an interface that defines the necessary variables and functions to provide the functionality defined by the interface, in the C language, one implementation is provided by one or more. c files, and an implementation must provide the functionality specified by the interface to which it is exported. The implementation should contain the. h file of the interface to ensure that its definition is consistent with the declaration of the interface.

Arith_min and Arith_max return the minimum and maximum values in their integer parameters:

int Arith_max (int x, int y) {return
  x > y x:y;
}
int arith_min (int x, int y) {return
  x > y y:x;
}

Arith_div returns the quotient of y divided by X, Arith_mod returns the corresponding remainder. When x is the same number as Y, Arith_div (x,y) is equivalent to X/y,arith_mod (x,y) equivalent to X%y

When x is different from the Y symbol, the return value of C's inline operation depends on the specific implementation:

If -13/5=2,-13%5=-3, if -13/5=-3,-13%5=2

The standard library functions are always rounded to 0, so the semantics of Div ( -13,2) =-2,arith_div and Arith_mod are also defined: they always approach the left edge of the axis, so Arith_div ( -13,5) =-3,arith_div (x,y) is the largest integer that does not exceed the real z, where Z satisfies the z*y=x.

Arith_mod (x,y) is defined as X-y*arith_div (x,y). So Arith_mod ( -13,5) =-13-5* (-3) =2

function arith_ceiling and Arith_floor follow a similar convention, arith_ceiling (x,y) returns the smallest integer not less than the real quotient x/y

Arith_floor (x,y) returns the largest integer that does not exceed the quotient x/y of the real number

The complete implementation code is as follows:

#include "arith.h"
int arith_max (int x, int y) {return
  x > y x:y;
}
int arith_min (int x, int y) {return
  x > y y:x;
}
int arith_div (int x, int y) {
  if ( -13/5 = = 2
  &&  (x < 0)!= (Y < 0) && x%y!= 0)
    R Eturn x/y-1;
  else return
    x/y;
}
int arith_mod (int x, int y) {
  if ( -13/5 = = 2
  &&  (x < 0)!= (Y < 0) && x%y!= 0) 
   
    return x%y + y;
  else return
    x%y;
}
int Arith_floor (int x, int y) {return
  arith_div (x, y);
}
int arith_ceiling (int x, int y) {return
  arith_div (x, y) + (x%y!= 0);
}

   

Abstract data type

An abstract data type (abstract Type,adt) is an interface that defines the data type and the various operations provided based on that type value

An advanced type is abstract because the interface hides its presentation details, lest the client invoke the program to rely on these details. The following is a canonical example of an abstract data type (ADT)-the stack, which defines the type and five actions:

#ifndef stack_included
#define stack_included
#define T stack_t
typedef struct T *t;
extern T   stack_new (void);
extern int  stack_empty (T Stk);
extern void Stack_push (T stk, void *x);
extern void *stack_pop (T stk);
extern void Stack_free (T *stk);
#undef T
#endif

Realize

Include Related header files:

#include <stddef.h>
#include "assert.h"
#include "mem.h"
#include "stack.h"
#define T stack_t

The interior of the stack_t is a structure that has fields that point to a list of pointers within a stack and a count of these pointers:

struct T {
  int count;
  struct Elem {
    void *x;
    struct Elem *link;
  } *head;
};

Stack_new assigns and Initializes a new T:

T stack_new (void) {
  T Stk;
  NEW (Stk);
  Stk->count = 0;
  Stk->head = NULL;
  return STK;
}

Where new is an Assignment macro directive in one of the other interfaces. New (P) assigns an instance of the struct and assigns its pointer to P, so it can be used in stack_new to assign a new stack_t

When count=0, Stack_empty returns 1, otherwise it returns 0:

int Stack_empty (T stk) {
  assert (Stk);
  return stk->count = = 0;
}

ASSERT (Stk) implements a checked run-time error that prevents null pointers from being passed to any function in the stack.

Stack_push and Stack_pop Add or remove elements from the head of the linked list that Stk->head points to:

void Stack_push (T stk, void *x) {
  struct elem *t;
  ASSERT (Stk);
  NEW (t);
  t->x = x;
  T->link = stk->head;
  Stk->head = t;
  stk->count++;
}
void *stack_pop (T stk) {
  void *x;
  struct Elem *t;
  ASSERT (Stk);
  ASSERT (Stk->count > 0);
  t = stk->head;
  Stk->head = t->link;
  stk->count--;
  x = t->x;
  Free (t);
  return x;
}

Free is the release macro directive defined in another interface that frees the space pointed to by the pointer argument and then sets the parameter to a null pointer

void Stack_free (T *stk) {
  struct elem *t, *u;
  ASSERT (Stk && *stk);
  for (t = (*STK)->head; t = u) {
    U = t->link;
    Free (t);
  }
  Free (*STK);
}

The complete implementation code is as follows:

#include <stddef.h>
#include "assert.h"
#include "mem.h"
#include "stack.h"
#define T stack_t
struct T {
  int count;
  struct Elem {
    void *x;
    struct Elem *link;
  } *head;
};
T stack_new (void) {
  T Stk;
  NEW (Stk);
  Stk->count = 0;
  Stk->head = NULL;
  return STK;
}
int Stack_empty (T stk) {
  assert (Stk);
  return stk->count = = 0;
}
void Stack_push (T stk, void *x) {
  struct elem *t;
  ASSERT (Stk);
  NEW (t);
  t->x = x;
  T->link = stk->head;
  Stk->head = t;
  stk->count++;
}
void *stack_pop (T stk) {
  void *x;
  struct Elem *t;
  ASSERT (Stk);
  ASSERT (Stk->count > 0);
  t = stk->head;
  Stk->head = t->link;
  stk->count--;
  x = t->x;
  Free (t);
  return x;
}
void Stack_free (T *stk) {
  struct elem *t, *u;
  ASSERT (Stk && *stk);
  for (t = (*STK)->head; t = u) {
    U = t->link;
    Free (t);
  }
  Free (*STK);
}

It is believed that this article has certain reference value to everybody's C programming.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.