C/C++ Thread

Ankur

Active Member
Hey guys I am thinking about mastering C and C++ this year. I have now 3 years of experience in C, C++ but I still think I need to learn a ton. What do you guys think, can you recommend me a good book?
 

Troncoso

VIP Member
Hey guys I am thinking about mastering C and C++ this year. I have now 3 years of experience in C, C++ but I still think I need to learn a ton. What do you guys think, can you recommend me a good book?

You should tell us what you know and if there are any aspects you know about but want to learn more of.
 

Ankur

Active Member
I know all the fundamentals, basics, graphics in C basics, data structures, all the OOP concepts, quite much of inbuilt ASM. Just want to know a book where I can master these all.
 

mihir

VIP Member
I know all the fundamentals, basics, graphics in C basics, data structures, all the OOP concepts, quite much of inbuilt ASM. Just want to know a book where I can master these all.

You know OOPs concepts in C?
That is some advanced stuff.
If you want to learn more stuff about OOPs in C
http://www.planetpdf.com/codecuts/pdfs/ooc.pdf
And if you want to learn some more C syntax and concepts, try this book
http://ubuntuone.com/3fqhi1ftepRCXEfdKoXwEG
Kerninghan And Ritchie. The creators of C.
 

Troncoso

VIP Member
I'm having trouble with a simple structs assignment. I'm getting errors that I feel like should be getting. The first one is "undefined reference to 'createPerson" and it points to the main.c file. Here are all the files used.

main.c
Code:
#include <stdio.h>
#include <stdlib.h>
#include "modifyPerson.h"

int main(int argc, char *argv[])
{
    char name[] = "Name";
    createPerson (name, 21, 180.0, 23, 2, 1991);

    return 0;
}

modifyPerson.h
Code:
void createPerson(char *name, int age, float height, int day, int month, int year);

void printPerson();

modifyPerson.c
Code:
#include <stdio.h>
#include <stdlib.h>
#include "person.h"

void createPerson(char *name, int age, float height, int day, int month, int year)
{
    Person newPerson = (Person) malloc (sizeof (Person));
    newPerson.name = name;
    newPerson.age = age;
    newPerson.height = height;
    newPerson.dob.day = day;
    newPerson.dob.month = month;
    newPerson.dob.year = year;

    return newPerson;
}

void printPerson(Person person)
{
    puts (person.name);
    printf ("%d\n%.2f\n", person.age);
    printf ("%d/%d/%d", person.dob.day, person.dob.month, person.dob.year);
}

person.h
Code:
typedef struct {
    int day;
    int month;
    int year;
} DoB;

typedef struct {
    char name[20];
    float height;
    DoB birthDate;
} Person;


If I remove the function call from main, then it will compile just fine. But I need to run that method.
 

TrainTrackHack

VIP Member
How are you trying to compile it? The only things I can think of that could cause an undefined reference error are that for some reason either modifyPerson.c is not being compiled at all (did you remember to put it in the list of sources to compile?) or the object file is not being passed to the linker, so main.c compiles fine but the linker goes boinkers when it realises that you haven't actually provided the object file in which createPerson and printPerson are contained.

However, not sure if this is related to the undefined reference errors, but you're returning a value from the createPerson method which you've declared as a void. Also, you're trying to assign a pointer value into the struct - you'll either need to just get rid of the malloc (this seems like what you want to do and you can safely do this unless your assignment requires you to allocate memory dynamically) or change newPerson to a pointer type (declare it as a *newPerson rather than newPerson) and then change all you assignments to dereference the pointer (i.e. newPerson.name = name becomes newPerson->name = name).
 

Cromewell

Administrator
Staff member
Yeah that code is weird. Pretty much everything I've got is covered by hackapelite.

One thing though, what if I pass more than 20 characters in as a name? ;)
 

Troncoso

VIP Member
The code is weird because I've been messing with it a lot just to get it to compile. The "createPerson" function is suppose to return a Person, which is a struct that is defined in person.h.

Though, I feel retarded now... when I was compiling I wasn't including the modifyPerson.c..... Hahaha.

Still, when I change modifyPerson.h to this (which is why I changed it to void):

Code:
Person createPerson(char *name, int age, float height, int day, int month, int year);

void printPerson();

I get this error:

modifyPerson.h:1: error: expected â=â, â,â, â;â, âasmâ or â__attribute__â before âcreatePersonâ

However, not sure if this is related to the undefined reference errors, but you're returning a value from the createPerson method which you've declared as a void. Also, you're trying to assign a pointer value into the struct - you'll either need to just get rid of the malloc (this seems like what you want to do and you can safely do this unless your assignment requires you to allocate memory dynamically) or change newPerson to a pointer type (declare it as a *newPerson rather than newPerson) and then change all you assignments to dereference the pointer (i.e. newPerson.name = name becomes newPerson->name = name).

Also, could you explain that a little better? I feel this is the source to several of my other errors.

One thing though, what if I pass more than 20 characters in as a name?

Haha. Yeah, I know. But for the assignment, he isn't requiring exception handling, because we are just focusing on structs.

And one last thing, am I including my headers the proper way? I get errors if I include a header in more than one place, but I'm not sure where to include them so they are properly linked.
 
Last edited:

TrainTrackHack

VIP Member
Also, could you explain that a little better? I feel this is the source to several of my other errors.
Well first, functions defined as void do not return a value, but you already fixed that. The other point is the malloc. When you do
Code:
int i;
Person p;
type identifier;
insude a method, you automatically get the required storage allocated on the stack so you are free to use it as is. However, you're allocating memory on the heap using malloc, which returns a pointer to the new block of data - not only do you never use this storage or even free it, you're forcibly ramming the pointer value into the struct using a cast (most likely the first 4 or 8 bytes of the struct, that is the first characters of the name field, are set to seeminlg garbage values which you overwrite when you assign the values). The heap allocation here is useless - in general, every time you use malloc, you should be assigning the return value to a pointer (the identifier of which is prefixed by an asterisk). If you ever see something like
Code:
type identifier = malloc(num);
instead of
Code:
type *identifier = malloc(num);
and you're positive that the identifier is not just a typedef for a pointer, alarm bells should be going off in your head. Just getting rid of the malloc (leaving you wuth just Person newPerson; ) should fix this.

And one last thing, am I including my headers the proper way? I get errors if I include a header in more than one place, but I'm not sure where to include them so they are properly linked.
Did you remember to put in any include guards? All header files are generally wrapped in something like
Code:
#ifndef HEADER_NAME_H_
#define HEADER_NAME_H_

/* all header contents go here */ 

#endif
to make sure that the header is processed only once even though it might be included in multiple files. What it simply does is check if the HEADER_NAME_H_ macro has been defined and if not, it defines it and includes everything up to the endif. The next time the same include file is encountered, the preprocessor sees that HEADER_NAME_H_ has already been defined, and simply skips everything up to the endif, ensuring that everything in the file gets included only once.

A quick question, by the way - have by any chance learned Java before C?
 

Troncoso

VIP Member
Thanks a lot for the help, mate. Keeping your words in mind, I was able to go back through my code and sort it out. All works as it should. Now my next assignment is to write an interpreter.....Hahaha.

And....yeah, I did. What gave it away?
 

TrainTrackHack

VIP Member
And....yeah, I did. What gave it away?
A lot of Java programmers new to a language like C or C++ often forget that non-primitive types (objects and structs) don't always need to be allocated dynamically using new... seeing someone trying to dynamically allocate memory where unnecessary/wrong is almost dead giveaway of a programmer who started off using Java (or some other language with similar reference semantics, but it's almost always Java) ^^
 

Troncoso

VIP Member
A lot of Java programmers new to a language like C or C++ often forget that non-primitive types (objects and structs) don't always need to be allocated dynamically using new... seeing someone trying to dynamically allocate memory where unnecessary/wrong is almost dead giveaway of a programmer who started off using Java (or some other language with similar reference semantics, but it's almost always Java) ^^

Haha. To be technical, I learned C++ before Java, but Java is my most prominent language.

I have one more question though, involving function pointers:

I have this struct:
Code:
typedef struct {
	void (*func)(instruction);
	union {
		double db;
		char ch;
	};
} instruction;

Within my source file, I have an array of these instructions. My question is, how would I loop through that array and execute each struct's function?

I thought I knew how to do this, but the fact that the instruction function has a parameter that is an instruction seems to cause problems. As such, this does not work:

Code:
int i;
	for (i = 0; i <= instr_count; i++) {
		(*instr[i].func) (instr[i]);
}

instr being the array of instructions.

Running the code gives me this runtime error:

"Unhandled exception at 0x00000000 in Interpreter.exe: 0xC0000005: Access violation."
 
Last edited:

Cromewell

Administrator
Staff member
Instead of
(*instr.func) (instr);
try
*(instr.func) (instr);

edit:
I'm guessing that it's getting confused on what to do, and hopefully changing the brackets will help. I try not to use structs and function pointers in general :p
 
Last edited:

Troncoso

VIP Member
I'm guessing that it's getting confused on what to do, and hopefully changing the brackets will help. I try not to use structs and function pointers in general :p

Haha. If that was an option, I'd definitely take that route. Not that C isn't a useful language, but again, given the option, I would not use it at all.
 

Cromewell

Administrator
Staff member
Haha. If that was an option, I'd definitely take that route. Not that C isn't a useful language, but again, given the option, I would not use it at all.

I've been fighting with this off and on all day, I still can't get it to work. :(

I'm going to keep trying but my god is it annoying.
 

Cromewell

Administrator
Staff member
I do mean your problem but I've got it now. I was thinking about what was wrong instead of working back from the error.

The gist of it is, you've made a pointer to a void function. But you haven't set that pointer equal to anything. This works as expected:
Code:
void func(int instruct) {
     printf("Instruction: %d", instruct);
}

typedef struct {
    void (* func)();
    union {
        double db;
        char ch;
    };
} instruction;

int main() {
    instruction *ins = malloc(sizeof(instruction));
    
    ins->db = 2.5;
    ins->ch = 'a';
    ins->func = &func;
    
    printf("db: %f ch: %c",ins->db, ins->ch);
    ins->func(5);

    return 0;
}
 

TrainTrackHack

VIP Member
This probably has nothing to do with your error (I'm pretty sure Chromewell is on the right track there, it looks like the func isn't correctly initialised), but you pointer declaration in the struct is fishy.

Declaring it like this would be fine
Code:
[B]struct instruction {[/B]
	void (*func)(instruction);
	union {
		double db;
		char ch;
	};
};
.since the type "instruction" is known from the first line onwards. But you've declared it like this
Code:
typedef struct {
	[I]void (*func)(instruction);[/I]
	union {
		double db;
		char ch;
	};
[B]} instruction;[/B]
The name "instruction" isn't known until the last line, so when you declare the function pointer, the compiler doesn't actually know what "instruction" even is. It should at least give you a warning (I would have expected an error). In practice, what it really means in that when you do an actual function call, the compiler can't reliably check that you're passing it the correct arguments, so it will end up compiling fine but if you put in incompatible/wrong number of arguments you would most likely end up crashing the program. Of course, in your example you are passing the correct number and type of arguments, so I'm pretty sure that's not the root of your problem. In general, though, when you declare a struct using the latter (typedef) way, you're not supposed to use the name inside the struct.
 

Troncoso

VIP Member
I do mean your problem but I've got it now. I was thinking about what was wrong instead of working back from the error.

The gist of it is, you've made a pointer to a void function. But you haven't set that pointer equal to anything. This works as expected:
Code:
void func(int instruct) {
     printf("Instruction: %d", instruct);
}

typedef struct {
    void (* func)();
    union {
        double db;
        char ch;
    };
} instruction;

int main() {
    instruction *ins = malloc(sizeof(instruction));
    
    ins->db = 2.5;
    ins->ch = 'a';
    ins->func = &func;
    
    printf("db: %f ch: %c",ins->db, ins->ch);
    ins->func(5);

    return 0;
}


This didn't turn out to be the issue at all. My problem was using the "strtok" function. It returned strange results and caused crazy exceptions. I don't know if this is in the code I posted, but I ended up initializing the instructions
with

instruction next = {0};

which works just fine. My only issue now, is that atof() won't convert strings to doubles...

I really appreciate all the help guys. Between you and hackapelite, you've given me several angles to look at my program with to help figure out whats wrong.
 

galerecon

New Member
Hey guys, I have a question. I have a program that I wrote last night and I'm trying to figure out how to calculate the sum for each player as well as the dealer. I was going to use an array called " int playersum[8];" but it won't let me pass an array through parameters. This way, each placing in the array will contain the total count for the game (I have 7 players and 1 dealer).
Code:
// main.cpp

#include <iostream>
#include <Windows.h>
#include <stdio.h>
#include <cstdlib>
#include <ctime>       //Headers
#include <string>
#include <iomanip>
using namespace std;
 
void PrintHeader();
void ShuffleDeck (int[]);
int GetCard(int[]);                //Function Prototype
char GetSuit(int);
void DealCard(int[]);

//This function will go to a specific location on the screen with (x,y) coordinants.
        void gotoxy(int x, int y)
        {
                HANDLE hConsole = GetStdHandle ( STD_OUTPUT_HANDLE );
       
           if ( INVALID_HANDLE_VALUE != hConsole )
              {
                    COORD pos = {x, y};
                        SetConsoleCursorPosition ( hConsole, pos );
                        }
       
         return;
        }

//This function will take the deck and add a number to it so it's not empty.
		void ShuffleDeck (int deck[])
		{
		   int temp = 0, n = 0;
 
			for (int i = 0; i < 52; i++)
		          deck[i] = i;
 
		   return;
		}

//This function will return the suit picture of the card when called.     
        char getsuit(int SuitNum)
        {
                switch(SuitNum)
                {
                        case 1: return char(3);
                        case 2: return char(4);
                        case 3: return char(5);
                        case 4: return char(6);
                }
        }

//Main function
int main()
{
        int y, z;
        //int PlayerSum[8]; <-- I need to figure out how to keep count of the sum for each player and dealer.
	int deck[52],
        char HorS;
        bool test[7];
        srand(time(NULL));     // Variable Declarations
 
        PrintHeader();          // Print the "BlackJack" header.
        ShuffleDeck(deck);      // Gives each card a value so the array is not just empty.
        DealCard(deck);         // Deals two cards for each person but doesn't show 1 card for the dealer.

// This for loop will set each value for test[] array == 'true'. 
        for(int i = 0; i < 8; i++)
        {
                test[i] = true;
        }
 
//Checks if Player 1 wants to hit or stay
		z = 16;
		y = 8;

        while(test[1] == true)
        {
		gotoxy(0,z);
		cout << "Player 1: Hit(h) or Stay(s)? ";
                cin >> HorS;
		cout << endl;
                        if(tolower(HorS) == 'h')
                                {
				    gotoxy(9,y);
                                    GetCard(deck);
                                    y++;
				    z++;
                                }
                                else if(tolower(HorS) == 's')
                                {
				    gotoxy(11,y);
                                    cout << "XX";
				    z++;
                                    test[1] = false;       
                                }
        }
 
//Checks if Player 2 wants to hit or stay
		y = 8;

        while(test[2] == true)
        {
		gotoxy(0,z);
		cout << "Player 2: Hit(h) or Stay(s)? ";
                cin >> HorS;
		cout << endl;
                        if(tolower(HorS) == 'h')
                                {
				    gotoxy(19,y);
                                    GetCard(deck);
                                    y++;
				    z++;
                                }
                                else if(tolower(HorS) == 's')
                                {
				    gotoxy(21,y);
                                    cout << "XX";
				    z++;
                                    test[2] = false;       
                                }
        }
//Checks if Player 3 wants to hit or stay
		y = 8;

        while(test[3] == true)
        {
		gotoxy(0,z);
		cout << "Player 3: Hit(h) or Stay(s)? ";
                cin >> HorS;
		cout << endl;
                        if(tolower(HorS) == 'h')
                                {
				    gotoxy(29,y);
                                    GetCard(deck);
                                    y++;
				    z++;
                                }
                                else if(tolower(HorS) == 's')
                                {
				    gotoxy(31,y);
                                    cout << "XX";
				    z++;
                                    test[3] = false;       
                                }
        }
//Checks if Player 4 wants to hit or stay
		y = 8;

        while(test[4] == true)
        {
		gotoxy(0,z);
		cout << "Player 4: Hit(h) or Stay(s)? ";
                cin >> HorS;
		cout << endl;
                        if(tolower(HorS) == 'h')
                                {
				    gotoxy(39,y);
                                    GetCard(deck);
                                    y++;
				    z++;
                                }
                                else if(tolower(HorS) == 's')
                                {
				    gotoxy(41,y);
                                    cout << "XX";
				    z++;
                                    test[4] = false;       
                                }
        }
//Checks if Player 5 wants to hit or stay
		y = 8;

        while(test[5] == true)
        {
		gotoxy(0,z);
		cout << "Player 5: Hit(h) or Stay(s)? ";
                cin >> HorS;
		cout << endl;
                        if(tolower(HorS) == 'h')
                                {
				    gotoxy(49,y);
                                    GetCard(deck);
                                    y++;
				    z++;
                                }
                                else if(tolower(HorS) == 's')
                                {
				    gotoxy(51,y);
                                    cout << "XX";
				    z++;
                                    test[5] = false;       
                                }
        }
//Checks if Player 6 wants to hit or stay
		y = 8;

        while(test[6] == true)
        {
		gotoxy(0,z);
		cout << "Player 6: Hit(h) or Stay(s)? ";
                cin >> HorS;
		cout << endl;
                        if(tolower(HorS) == 'h')
                                {
				    gotoxy(59,y);
                                    GetCard(deck);
                                    y++;
				    z++;
                                }
                                else if(tolower(HorS) == 's')
                                {
				    gotoxy(61,y);
                                    cout << "XX";
				    z++;
                                    test[6] = false;       
                                }
        }
//Checks if Player 7 wants to hit or stay
		y = 8;

        while(test[7] == true)
        {
		gotoxy(0,z);
		cout << "Player 7: Hit(h) or Stay(s)? ";
                cin >> HorS;
		cout << endl;
                        if(tolower(HorS) == 'h')
                                {
				    gotoxy(69,y);
                                    GetCard(deck);
                                    y++;
				    z++;
                                }
                                else if(tolower(HorS) == 's')
                                {
				    gotoxy(71,y);
                                    cout << "XX";
				    z++;
                                    test[7] = false;       
                                }
        }
//Dealer reveals card and hits if < 17 or stays if > 17.
		gotoxy(0,z);
		cout << endl << "Dealer reveals second card.";
		
		gotoxy(0,6);
		GetCard(deck);

		getchar();
        getchar();
        return 0;
}
 
void PrintHeader()
{
        cout << "============================================================================" << endl
                 << "|                             "
                 << char(3) << " " << char(4) << " BlackJack " << char(5) << " " << char(6)
                 << "                            |" << endl
                 << "============================================================================" << endl << endl;
 
        cout << "Dealer  Player 1  Player 2  Player 3  Player 4  Player 5  Player 6  Player 7" << endl
                 << "------  --------  --------  --------  --------  --------  --------  --------" << endl;
 
        return;
}
 
int GetCard(int deck[])
{
        bool test = true;
        char suit;
        int CardNum, value;
 
        CardNum = rand() % 52;    // Gets a random number from 52 (deck).
 
        while(test == true)       // The while loop will make sure no cards are repeated.
        {
                if (deck[CardNum] == -1)
                        CardNum = rand() % 52;
                else
                {
                    value = deck[CardNum] %13;
                    test = false;
                }
        }
 
        deck[CardNum] = -1;
 
        if (value == 0)  
		{
			cout << setw(3) << "A";
			//sum += 1;
		}
        else if (value > 0 && value < 10)
		{
            		cout << setw(3) << (value + 1);
		}
        else if (value == 10)
		{
            		cout << setw(3) << "J";       //Prints out the value on the screen.
		}
        else if(value == 11)
		{
            		cout << setw(3) << "Q";
		}
        else if(value == 12)
		{
			cout << setw(3) << "K";
		}
 
        suit = GetSuit(CardNum);   // Gets the suit for the card.
        cout << suit;
 
        return value;
}

//Gets suit for the card.
char GetSuit(int CardNum)
{
        int value;
        char suit = 0;
 
        value = CardNum / 13;
 
        switch(value)
        {
                case 0: suit = char(3);
                        break;
                case 1: suit = char(4);
                        break;
                case 2: suit = char(5);
                        break;
                case 3: suit = char(6);
                        break;
        }
        return suit;
}

//Deals 2 cards for each person. Dealer only shows 1 card.
void DealCard(int deck[])
{ 
        gotoxy(0,6);
        cout << ">";
        gotoxy(0,7);   // Dealer
        GetCard(deck);
 
        gotoxy(9,6);
        GetCard(deck);  //Player 1
        gotoxy(9,7);
        GetCard(deck);
 
        gotoxy(19,6);
        GetCard(deck);  //Player2
        gotoxy(19,7);
        GetCard(deck);
 
        gotoxy(29,6);
        GetCard(deck);  //Player 3
        gotoxy(29,7);
        GetCard(deck);
 
        gotoxy(39,6);
        GetCard(deck);  //Player 4
        gotoxy(39,7);
        GetCard(deck);
 
        gotoxy(49,6);
        GetCard(deck);  //Player 5
        gotoxy(49,7);
        GetCard(deck);
 
        gotoxy(59,6);
        GetCard(deck);  //Player 6
        gotoxy(59,7);
        GetCard(deck);
 
        gotoxy(69,6);
        GetCard(deck);   // Player 7
        gotoxy(69,7);
        GetCard(deck);
       
        return;
}

I know it's a lot, but a lot of it is repeated over and over again. For example the function getcard and getsuit is called many times when a player hits or stays.

I just can't figure out how I can keep track of the sums (totals) for each player.
(Ace is a 1 not 11 and I'm only using one deck).

I would really appreciate for the help!
 
Last edited:
Top