У Iv есть программа, в которой уже написано несколько библиотек. Структура stackElementT была двойной, теперь ее нужно преобразовать в тип указателя void. Я понимаю, что мне нужно выделять память каждый раз, когда я нажимаю номер в стек, но не могу понять, что выделить. если я только преобразовать структуру типа пустоты *, то я получаю следующие ошибки:Преобразование структуры стека двойного типа void *
gcc -I../booklib -c rpncalc.c
In file included from rpncalc.c:14:0:
stack.h:65:41: warning: parameter 2 (‘element’) has void type [enabled by default]
void Push(stackADT stack, stackElementT element);
^
rpncalc.c: In function ‘main’:
rpncalc.c:44:17: error: type of formal parameter 2 is incomplete
Push(operandStack, StringToReal(line));
^
rpncalc.c: In function ‘ApplyOperator’:
rpncalc.c:69:9: error: void value not ignored as it ought to be
rhs = Pop(operandStack);
^
rpncalc.c:70:9: error: void value not ignored as it ought to be
lhs = Pop(operandStack);
^
rpncalc.c:79:12: error: incompatible types when assigning to type ‘double’ from type ‘void *’
result = malloc(result * sizeof(double *));
^
rpncalc.c:80:5: error: type of formal parameter 2 is incomplete
Push(operandStack, result);
^
rpncalc.c: In function ‘DisplayStack’:
rpncalc.c:135:13: error: invalid use of void expression
printf("%g", GetStackElement(stack, i));
^
make: *** [rpncalc.o] Error 1
здесь код stack.h:
/*
* File: stack.h
* -------------
* This interface defines an abstraction for stacks. In any
* single application that uses this interface, the values in
* the stack are constrained to a single type, although it
* is easy to change that type by changing the definition of
* stackElementT in this interface.
*/
#ifndef _stack_h
#define _stack_h
#include "genlib.h"
/*
* Type: stackElementT
* -------------------
* The type stackElementT is used in this interface to indicate
* the type of values that can be stored in the stack. Here the
* stack is used to store values of type double, but that can
* be changed by editing this definition line.
*/
typedef void stackElementT;
/*
* Type: stackADT
* --------------
* The type stackADT represents the abstract type used to store
* the elements that have been pushed. Because stackADT is
* defined only as a pointer to a concrete structure that is not
* itself defined in the interface, clients have no access to
* the underlying fields.
*/
typedef struct stackCDT *stackADT;
/*
* Function: NewStack
* Usage: stack = NewStack();
* --------------------------
* This function allocates and returns a new stack, which is
* initially empty.
*/
stackADT NewStack(void);
/*
* Function: FreeStack
* Usage: FreeStack(stack);
* ------------------------
* This function frees the storage associated with the stack.
*/
void FreeStack(stackADT stack);
/*
* Function: Push
* Usage: Push(stack, element);
* ----------------------------
* This function pushes the specified element onto the stack.
*/
void Push(stackADT stack, stackElementT element);
/*
* Function: Pop
* Usage: element = Pop(stack);
* ----------------------------
* This function pops the top element from the stack and returns
* that value. The first value popped is always the last one
* that was pushed. If the stack is empty when Pop is called,
* the function calls Error with an appropriate message.
*/
stackElementT Pop(stackADT stack);
/*
* Functions: StackIsEmpty, StackIsFull
* Usage: if (StackIsEmpty(stack)) . . .
* if (StackIsFull(stack)) . . .
* -------------------------------------
* This functions test whether the stack is empty or full.
*/
bool StackIsEmpty(stackADT stack);
bool StackIsFull(stackADT stack);
/*
* Function: StackDepth
* Usage: depth = StackDepth(stack);
* ---------------------------------
* This function returns the number of elements currently pushed
* on the stack.
*/
int StackDepth(stackADT stack);
/*
* Function: GetStackElement
* Usage: element = GetStackElement(stack, index);
* -----------------------------------------------
* This function returns the element at the specified index in
* the stack, where the top of the stack is defined as index 0.
* For example, calling GetStackElement(stack, 0) returns the top
* element on the stack without removing it. If the caller tries
* to select an out-of-range element, GetStackElement calls Error.
* Note: This function is not a fundamental stack operation and
* is instead provided principally to facilitate debugging.
*/
stackElementT GetStackElement(stackADT stack, int index);
#endif
и вот rpncalc.c, который делает толкание и выталкивание:
/*
* File: rpncalc.c
* ---------------
* This program simulates an electronic calculator that uses
* reverse Polish notation, in which the operators come after
* the operands to which they apply.
*/
#include <stdio.h>
#include <ctype.h>
#include "genlib.h"
#include "simpio.h"
#include "strlib.h"
#include "stack.h"
/* Private function prototypes */
static void ApplyOperator(char op, stackADT operandStack);
static void HelpCommand(void);
static void ClearStack(stackADT operandStack);
static void DisplayStack(stackADT operandStack);
/* Main program */
main()
{
stackADT operandStack;
string line;
char ch;
printf("RPN Calculator Simulation (type H for help)\n");
operandStack = NewStack();
while (TRUE) {
line = malloc(line * sizeof(double *));
printf("> ");
line = GetLine();
ch = toupper(line[0]);
switch (ch) {
case 'Q': exit(0);
case 'H': HelpCommand(); break;
case 'C': ClearStack(operandStack); break;
case 'S': DisplayStack(operandStack); break;
default:
if (isdigit(ch)) {
Push(operandStack, StringToReal(line));
} else {
ApplyOperator(ch, operandStack);
}
break;
}
}
}
/* Private functions */
/*
* Function: ApplyOperator
* Usage: ApplyOperator(op, operandStack);
* ---------------------------------------
* This function applies the operator to the top two elements on
* the operand stack. Because the elements on the stack are
* popped in reverse order, the right operand is popped before
* the left operand.
*/
static void ApplyOperator(char op, stackADT operandStack)
{
double lhs, rhs, result;
rhs = Pop(operandStack);
lhs = Pop(operandStack);
switch (op) {
case '+': result = lhs + rhs; break;
case '-': result = lhs - rhs; break;
case '*': result = lhs * rhs; break;
case '/': result = lhs/rhs; break;
default: Error("Illegal operator %c", op);
}
printf("%g\n", result);
result = malloc(result * sizeof(double *));
Push(operandStack, result);
}
/*
* Function: HelpCommand
* Usage: HelpCommand();
* ---------------------
* This function generates a help message for the user.
*/
static void HelpCommand(void)
{
printf("Enter expressions in Reverse Polish Notation,\n");
printf("in which operators follow the operands to which\n");
printf("they apply. Each line consists of a number, an\n");
printf("operator, or one of the following commands:\n");
printf(" Q -- Quit the program\n");
printf(" H -- Display this help message\n");
printf(" C -- Clear the calculator stack\n");
printf(" S -- Display all values in the stack\n");
}
/*
* Function: ClearStack
* Usage: ClearStack(stack);
* -------------------------
* This function clears the stack by popping elements until it is
* empty.
*/
static void ClearStack(stackADT stack)
{
while (!StackIsEmpty(stack)) {
(void) Pop(stack);
}
}
/*
* Function: DisplayStack
* Usage: DisplayStack(stack);
* ---------------------------
* This function displays the contents of a stack.
*/
static void DisplayStack(stackADT stack)
{
int i, depth;
printf("Stack: ");
depth = StackDepth(stack);
if (depth == 0) {
printf("empty\n");
} else {
for (i = depth - 1; i >= 0; i--) {
if (i < depth - 1) printf(", ");
printf("%g", GetStackElement(stack, i));
}
printf("\n");
}
}
всякая помощь приветствуется.
«теперь он должен быть преобразован в тип указателя пустоты». Таким образом, 'typedef void stackElementT;' должен быть 'typedef void * stackElementT;' – kaylum