2

I am given a few descriptions of macros and I have to define them.

DECL_LIST( type, name )

Expands to the declaration syntax for the three variables used in a resizable array implementation, name_len, name_cap and name (the pointer itself).

CHECK_CAP( type, name ) Expands to the code to make sure the resizable array has enough capacity for another element and to enlarge it if it doesn’t.

• SIZE( name )

Expands to an expression for the number of elements currently stored in the array.

• FOR( var, limit )

Expands to the first line of a for loop that uses an int variable named var to iterate from 0 up to (but not including) limit.

• SWAP( type, a, b )

Expands to a block of code that swaps the values of two variables a and b of the given type. We need the type parameter in order to declare a temporary variable that will help swap the values.

The logic is for this sorting function is already there. I just have to use the same logic in the macros in the manipulated function:

// Put your macro definitions here.  That should be all
// you need to do to complete this exercise.
#define DECL_LIST(type, name) \
    int name ## _cap = 5;     \
    int name ## _len = 0;     \
    type *name = (type *) malloc(name ## _cap * sizeof(type)); 

#define CHECK_CAP(type, name)                                         \
if ( name ## _len >= name ## _cap ) {                                 \
name ## _cap *= 2;                                                    \
name = (type *) realloc(name, name ## _cap * sizeof(type)); \
}  

#define SIZE(name)    \
sizeof(name)/sizeof(name[0]) 


#define FOR(var, limit) { \
  int var = 0;  \
for( int i = 0; i < limit; i++) {          \
       var++;           \
}    \
}

#define SWAP(type, a, b)   \
type temp = a; \
   a = b; \
   b = temp; 


int main()
{
  // Make a resizable list.
  DECL_LIST( double, list );

  double val;
  while ( scanf( "%lf", &val ) == 1 ) {
    // Grow the list when needed.
    CHECK_CAP( double, list );

    // Add this item to the list
    list[ SIZE( list ) ] = val;
    SIZE( list ) += 1;
  }

  // Bubble-sort the list.
  FOR( i, SIZE( list ) )
    FOR( j, SIZE( list ) - i - 1 )
      if ( list[ j ] > list[ j + 1 ] )
        SWAP( double, list[ j ], list[ j + 1 ] );

  // Print out the resulting, sorted list, one value per line.
  FOR( i, SIZE( list ) )
    printf( "%.2f\n", list[ i ] );

  return EXIT_SUCCESS;
}

This was the original main function before it was converted:

#include <stdio.h>
#include <stdlib.h>
int main()
{
// Make a resizable list.
int list_cap = 5;
int list_len = 0;
double *list = (double *) malloc( list_cap * sizeof( double ) );
double val;
while ( scanf( "%lf", &val ) == 1 ) {
// Grow the list when needed.
if ( list_len >= list_cap ) {
list_cap *= 2;
list = (double *) realloc( list, list_cap * sizeof( double ) );
}
// Add this item to the list
list[ list_len ] =val;
list_len++;
}
// Bubble-sort the list.
for ( int i = 0; i < list_len; i++ )
for ( int j = 0; j < list_len - i - 1; j++ )
if ( list[ j ] > list[ j + 1 ] ) {
double tmp = list[ j ];
list[ j ] = list[ j + 1 ];
list[ j + 1 ] = tmp;
}
// Print out the resulting, sorted list, one value per line.
for ( int i = 0; i < list_len; i++ )
printf( "%.2f\n", list[ i ] );
return EXIT_SUCCESS;
}

This is the compiler output after making some recommended changes:

error: lvalue required as left operand of assignment
     SIZE( list ) += 1;
                  ^
sortList.c:50:8: warning: unused variable ‘i’ [-Wunused-variable]
   FOR( i, SIZE( list ) )
        ^
sortList.c:22:7: note: in definition of macro ‘FOR’
   int var = 0;  \
       ^
sortList.c:52:18: error: ‘j’ undeclared (first use in this function)
       if ( list[ j ] > list[ j + 1 ] )
                  ^
sortList.c:52:18: note: each undeclared identifier is reported only once for each function it appears in
sortList.c:53:15: error: expected expression before ‘double’
         SWAP( double, list[ j ], list[ j + 1 ] );
               ^
sortList.c:29:1: note: in definition of macro ‘SWAP’
 type temp = a; \
 ^
sortList.c:31:8: error: ‘temp’ undeclared (first use in this function)
    b = temp; 
        ^
sortList.c:53:9: note: in expansion of macro ‘SWAP’
         SWAP( double, list[ j ], list[ j + 1 ] );
         ^
sortList.c:56:8: warning: unused variable ‘i’ [-Wunused-variable]
   FOR( i, SIZE( list ) )
        ^
sortList.c:22:7: note: in definition of macro ‘FOR’
   int var = 0;  \
       ^
sortList.c:57:29: error: ‘i’ undeclared (first use in this function)
     printf( "%.2f\n", list[ i ] );

Any suggestions if my current macros are correct? I am kind of confused on the descriptions.

3
  • 1
    Is there a question here? Commented Mar 21, 2019 at 21:52
  • oops, forgot to include it. Question updated. Commented Mar 21, 2019 at 21:56
  • 1
    Your macros are wrapped in { }. You don't want that. Commented Mar 21, 2019 at 22:15

1 Answer 1

3

You teacher wants you to use C preprocessor token pasting to create a macro that replaces the code. For example, the first macro would look like this

#define DECL_LIST(type, name) \
    int name ## _cap = 5; \
    int name ## _len = 0; \
    type *name = (type *) malloc(name ## _cap * sizeof(type));

and would replace this code

// Make a resizable list.
int list_cap = 5;
int list_len = 0;
double *list = (double *) malloc( list_cap * sizeof( double ) );

Regarding your questions about the CHECK_CAP macro, your teacher wants you to replace this code with a macro

// Grow the list when needed.
if ( list_len >= list_cap ) {
    list_cap *= 2;
    list = (double *) realloc( list, list_cap * sizeof( double ) );
}

but leave this code intact

// Add this item to the list
list[ list_len ] =val;
list_len++;

Later, you can replace list_len with your SIZE macro.

Hopefully, this will help you understand why the macro doesn't need to modify list_len.

FOR should be

#define FOR(var, limit) \
    for (int var = 0; var < limit; var++)

You need to use braces around SWAP because it expands to multiple lines:

  if ( list[ j ] > list[ j + 1 ] ) {
     SWAP( double, list[ j ], list[ j + 1 ] );
  }
Sign up to request clarification or add additional context in comments.

8 Comments

So, for the second one, how would the macro know if the size of the array needs to be resized? It doesn't know the updated size after insertion of the data.
It checks the capacity before the insertion: if ( list_len >= list_cap )
But how does list_len get set to the length of the list?
The list_len isn't affected when the capacity is increased.
In your answer, you used *list for pointer. Shouldn't it be *name since we don't know what the name of the pointer will be?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.