简体   繁体   中英

Function pointer declared in struct for graph, assign same function

Basically i cant make work this logic simulator! I made an adjacency list that connects all the gates one to each other and then assign a value to them and AdjList that is the head should calculate the value using the function pointer. Problem is the only function it calls is And!(Xor Nand etc.. are never called) The specific points are where pointer are initialized

struct AdjList
{
    struct AdjListNode *head;
    string GateName;
    string OutputName;
    bool result;
    function <bool (vector <bool>)> ptrf;

};

and were they are assigned

      if(i < Gate_IO.size() )
        {
            ptrPos = Gate_IO[i].find_first_of(' ');
            switch (strtoi ( (Gate_IO[i].substr(0,ptrPos).c_str() )))
            {
                case strtoi("AND"):
                    {   
                        VectorHeadPtr[i].ptrf = And;
                        break;
                    }
                case strtoi("NAND"):
                    {   
                        VectorHeadPtr[i].ptrf = Nand;
                        break;
                    }
                case strtoi("OR"):
                    {   
                        VectorHeadPtr[i].ptrf = Or;
                        break;
                    }
                case strtoi("NOR"):
                    {   
                        VectorHeadPtr[i].ptrf = Nor;
                        break;
                    }
                case strtoi("XOR"):
                    {  
                        VectorHeadPtr[i].ptrf = Xor;
                        break;
                    }
                default:
                        break;
            }

Then in function CalcGateValue() they are called to execute the program! it seems like they are recognised and assigned to the right value in VectorHeadPtr[i].ptrf i tried to cout in that point and it goes into that cycle but the only function called when i call CalcGateValue() is And! Am I missing something? Here is the complete code:

#include <iostream>
#include <cstdlib>
#include <string>
#include <sstream>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;
int compare(string a, string b)
{
    int n = count(a.begin(), a.end(), 'I');
    int q = count(b.begin(), b.end(), 'I');
    return n > q;
}
constexpr unsigned int strtoi(const char* str, int h = 0) //string to int for switch cycle
{
    return !str[h] ? 5381:(strtoi(str, h+1)*33)^str[h];
}
        bool Xor(vector<bool> inputs)
        {  cout<<"Xor function called!"<<endl;
            int counter = 0;
            for (unsigned int i = 0;i < inputs.size(); i++)
            {
                if (inputs.at(i) == 1)
                {
                    counter++;
                }
            }
            if (counter % 2) //Xor gate gives output 1 if and odd number of 1 inputs is given
            {
                return 1;
            }
            else
            {
                return 0;
            }
        }

        bool And(vector<bool> inputs) //static per richiamare la funzione dalla classe
        {   cout<<"And function called!"<<endl;
            for (int i = 0; i < (inputs.size()-1); i++)
                {
                    if(inputs.at(i) == 0)
                    {
                        return 0;
                    }
                }
            return 1;
        }
        bool Nand(vector<bool> inputs)
        { cout<<"Nand function called!"<<endl;
        return !And(inputs);
        }
        bool Or(vector<bool> inputs)
        {cout<<"Or function called!"<<endl;
            for (int i = 0; i < (inputs.size()-1); i++)
            {
                if (inputs.at(i) != inputs.at(i+1) )
                {
                    return 1;
                }
            }
            return inputs.at(0);//Any position it's ok because all nPoss are the same.
        }
        bool Nor(vector<bool> inputs)
        { cout<<"Nor function called!"<<endl;
            return !Or(inputs);
        }
/*
 * Adjacency list node
 */
struct AdjListNode
{
    int nPos;
    bool gValue;
    string name;
    struct AdjListNode* next;
};

/*
 * Adjacency list
 */
struct AdjList
{
    struct AdjListNode *head;
    string GateName;
    string OutputName;
    bool result;
    function <bool (vector <bool>)> ptrf;

};

/**
 * Class Graph
 */
class Graph
{
    private:
        int V;
        int circInputs = 3;
        int circOutputs = 2;
        int circGates;
        int PrimaryInputs = 0;
        vector<string> ioPuts;
        struct AdjList* VectorHeadPtr;
    public:
        Graph(vector<string> Gate_IO)
        {
            int ptrPos,cntr;
            int cntrIO = 0;
            int prevPrimaryInputs = 0;
            bool flag_remove_duplicates = 0;
            string GateToConnect;
            circGates = Gate_IO.size();
            V=Gate_IO.size() + circInputs + circOutputs; //n°gates+input+output letti dal file
            sort (Gate_IO.begin(), Gate_IO.end(), compare);
            for (cntr = 0; cntr < (Gate_IO.size()-1) && (PrimaryInputs == prevPrimaryInputs); cntr++)
            {
                PrimaryInputs = count (Gate_IO[cntr+1].begin(), Gate_IO[cntr+1].end(), 'I');
                prevPrimaryInputs = count (Gate_IO[cntr].begin(), Gate_IO[cntr].end(), 'I');
            }
            PrimaryInputs = cntr; //Here starts first N
            for (int i = 0;i<Gate_IO.size();i++)
            VectorHeadPtr = new AdjList [V];
            for (int i = 0; i < V; i++)
            {
                if(i < Gate_IO.size() )
                {
                    ptrPos = Gate_IO[i].find_first_of(' ');
                    switch (strtoi ( (Gate_IO[i].substr(0,ptrPos).c_str() )))
                    {
                        case strtoi("AND"):
                            {
                                VectorHeadPtr[i].ptrf = And;
                                break;
                            }
                        case strtoi("NAND"):
                            {
                                VectorHeadPtr[i].ptrf = Nand;
                                break;
                            }
                        case strtoi("OR"):
                            {
                                VectorHeadPtr[i].ptrf = Or;
                                break;
                            }
                        case strtoi("NOR"):
                            {
                                VectorHeadPtr[i].ptrf = Nor;
                                break;
                            }
                        case strtoi("XOR"):
                            {
                                VectorHeadPtr[i].ptrf = Xor;
                                break;
                            }
                        default:
                                break;
                    }
                    VectorHeadPtr[i].head = NULL;
                    stringstream ss;
                    ss << Gate_IO[i];
                    for (string temp; ss >> temp;)
                    {
                        if ( (temp.at(0)=='I') || (temp.at(0)=='O') && (temp!="OR") )
                        {
                            ioPuts.push_back(temp);
                        }
                        else if (temp.at(0) == 'U')
                        {
                            VectorHeadPtr[i].GateName=temp;
                        }
                    }
                    ptrPos = Gate_IO[i].find_last_of(' ');
                    VectorHeadPtr[i].OutputName = Gate_IO[i].substr(ptrPos);
                }
                else
                {
                    if (flag_remove_duplicates == 0)
                       {
                            sort (ioPuts.begin(), ioPuts.end() );
                            ioPuts.erase (unique (ioPuts.begin(), ioPuts.end() ), ioPuts.end() );
                            flag_remove_duplicates = 1;
                       }
                    VectorHeadPtr[i].head = NULL;
                    VectorHeadPtr[i].ptrf = NULL;
                    VectorHeadPtr[i].GateName = ioPuts[cntrIO];
                    cntrIO++;
                }
            }
            for (int i = 0; i < Gate_IO.size(); i++)
            {
                for(int j = 0; j < 2; j++)
                {
                    ptrPos = Gate_IO[i].find_first_of(' ')+1;
                    Gate_IO[i].erase (0,ptrPos);
                }
                ptrPos = Gate_IO[i].find_last_of(' ')+1;
                Gate_IO[i].erase( ptrPos);
                stringstream ss;
                ss << Gate_IO[i];
                ss >> GateToConnect;
                for (string temp; ss >> temp;)
                {
                    addEdge(GateToConnect,temp);
                }
            }
        }
        /**
         * Creates new adjacency list node for addEdge function
         */
        AdjListNode* newAdjListNode(int nPos, string Name)
        {
            AdjListNode* newNode = new AdjListNode;
            newNode->nPos = nPos;
            newNode->name = Name;
            newNode->next = NULL;
            return newNode;
        }
        /**
         * Add edge to graph
         */
        void addEdge(string source, string destination)
        {
            int from, to;
            for (int i = 0; i < V; ++i)
            {
                if ( (source == VectorHeadPtr[i].GateName) || (source == VectorHeadPtr[i].OutputName) )
                {
                    from = i;
                }
                else if (( destination == VectorHeadPtr[i].GateName) || (destination == VectorHeadPtr[i].OutputName) )
                {
                    to = i;
                }
            }
            AdjListNode* newNode = newAdjListNode(to, destination);
            newNode->next = VectorHeadPtr[from].head;
            VectorHeadPtr[from].head = newNode;
        }
        /*
         * Print the graph
         */
        void printGraph()
        {
            for (int i = 0; i < circGates; i++)//meno ooutput+input
            {
                AdjListNode* Ptr = VectorHeadPtr[i].head;
                cout<<endl<<"Gate connections for "<<VectorHeadPtr[i].GateName;
                while (Ptr)
                {
                    cout <<"-> "<< Ptr->name;
                    Ptr = Ptr->next;
                }
                cout<<" Output name is:"<<VectorHeadPtr[i].OutputName<<endl;
            }
        }
        void calcGateVal()
        {
            vector<bool> Val={0, 1, 0};
            vector<bool> Op;
            for (int i = 0; i < circOutputs; i++)
            {
                ioPuts.pop_back();
            }
            for (int i = 0; i < circGates; i++)
            {
                AdjListNode* Ptr = VectorHeadPtr[i].head;
                while (Ptr)
                {
                    if (Ptr->name.at(0) == 'I')
                    {
                        for (int j = 0; j < ioPuts.size(); j++)
                        {
                            if (Ptr->name == ioPuts[j])
                            {
                                Ptr->gValue = Val[j];
                            }
                        }
                    }
                    Ptr = Ptr->next;
                }
            }
            for (int i = 0; i < PrimaryInputs; i++)
            {
                AdjListNode* Ptr = VectorHeadPtr[i].head;
                while (Ptr)
                {
                    Op.push_back(Ptr->gValue);
                    Ptr = Ptr->next;
                }
                VectorHeadPtr[i].result = VectorHeadPtr[i].ptrf(Op);
                cout<<"Gate Value is: "<<VectorHeadPtr[i].result<<" OutputName: "<<VectorHeadPtr[i].OutputName<<" GateName: "<<VectorHeadPtr[i].GateName<<endl;
                Op.clear();
            }
            for (int i = PrimaryInputs; i < V; i++)
            {
                AdjListNode* Ptr = VectorHeadPtr[i].head;
                while (Ptr)
                {
                        for (int j = 0; j < PrimaryInputs; j++)
                        {
                            if (Ptr->name == VectorHeadPtr[j].OutputName)
                            {
                                Ptr->gValue = VectorHeadPtr[j].result;
                            }
                        }
                    Ptr = Ptr->next;
                }
            }
            for (int i = PrimaryInputs; i < circGates; i++)
            {
                AdjListNode* Ptr = VectorHeadPtr[i].head;
                while (Ptr)
                {
                    Op.push_back(Ptr->gValue);
                    Ptr = Ptr->next;
                }
                VectorHeadPtr[i].result = VectorHeadPtr->ptrf(Op);
                Op.clear();
            }
        }
        void displayOutput()
        {   cout<<endl;
            for (int i = 0; i < circGates; i++)
            {
                cout<<"Value of outputs are ("<<VectorHeadPtr[i].GateName<<") "<<VectorHeadPtr[i].OutputName<<": "<<VectorHeadPtr[i].result<<endl;
            }
        }
};
/*
 * Main
 */
int main()
{
    vector<string> G_d;
    G_d.push_back("AND 2 U0 I0 I1 N0");
    G_d.push_back("XOR 2 U1 N0 I2 O0");
    G_d.push_back("AND 2 U2 N0 I2 N1");
    G_d.push_back("AND 2 U3 I0 I1 N2");
    G_d.push_back("OR 2 U4 N1 N2 O1");
    Graph gh(G_d);
    gh.calcGateVal();
    gh.displayOutput();
    gh.printGraph();

    // print the adjacency list representation of the above graph

    return 0;
}

I think your code does not produce what you say it produces. Please see here:

http://coliru.stacked-crooked.com/a/405b04c8d9113790 - Check the output of this

Why do you want to convert strings to integers with strtoi with your case comparisons? :

case strtoi("NAND"):

  • a better approach would be strcmp or store each in a string perhaps a look up table and do a "==" equal equal comparison which is overloaded for strings.

Consider passing your vectors and objects around by reference rather than value, you might be expecting a return in your object but since you pass by value you never see them and this also avoids the overhead of making a copy of the vectors.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM