• Hey, guest user. Hope you're enjoying NeoGAF! Have you considered registering for an account? Come join us and add your take to the daily discourse.

Programming |OT| C is better than C++! No, C++ is better than C

Haly

One day I realized that sadness is just another word for not enough coffee.
Did you double check that you were reading in the data properly? It's probably a logic error somewhere.
 
malloc doesn't fail in that manner. If malloc had failed to allocate all the memory you requested, it would return NULL, which would cause a SIGSEGV crash when you dereferenced the array pointer.

The issue is probably not malloc-related.

Yeah. That's why I was initially confused cause I thought it would've thrown an error if it hadn't allocated enough. But it didn't and I was lost cause I missed that I accidentally passed the wrong variable to malloc and didn't notice.

Did you double check that you were reading in the data properly? It's probably a logic error somewhere.

I had to rewrite a few lines, and I ended passed the wrong variable to malloc. Whoops. I had to split up the data amongst n processes and in calculating how much to send (n/p) I ended up passing the chunksize to the malloc call and not the total size of the number of elements it was reading in. :\
 
I've got to knock some rust off my VB this weekend. Have an interview this week for a different position within my large, too big to fail bank employer, that's a mix of maintenance development in VB and new development in C#. Haven't used VB.NET in years. Fortunately, it's mostly just a syntactical difference from C# over the top of the same BCL, but still.
 

phoenixyz

Member
I feel like my biggest problem is just getting started since I haven't done any heavy programming in so long. While I get the ideas behind what I need to do, I just feel a bit stuck when it comes to actually starting it.
A good place to start would be to actually read in the files and prepare the data for what you want to do. Next you can loop over the numbers and build the "decoded" string with them.
 

Water

Member
I feel like my biggest problem is just getting started since I haven't done any heavy programming in so long. While I get the ideas behind what I need to do, I just feel a bit stuck when it comes to actually starting it.
Start by writing your plan of attack as comments. Really general at first, something like:
// read sentence from file
// establish translation from sentence
// read the rest
// ... and decode using translation

Then keep drilling down and breaking down each part, writing more comments/pseudocode, until it starts to feel silly and it's simpler to just write the code in a given section rather than spell things out further.

When you start writing actual code, try to do it in order. Try to establish the beginning of your code compiles and works correctly (using debug printing or whatever) before moving to the next part and building on it.
 
Ok, so the program I've been working on (C) for a while has had this memory-leakesque type problem wherein one of the values in my structs has been sharing a memory location with a pointer I malloced.

Basically, I gave memory to the struct first although the values inside were null since they're pointers as well. I then allocated memory for a double pointer of type char. The problem is that I allocated memory for the second pointer but it seems to have allocated memory to infinity. Here's some info from gdb:
Code:
38		alias = malloc(sizeof(struct user_cmd));
11: alias[0] = {
  name = 0xffff0f850ffff883 <Address 0xffff0f850ffff883 out of bounds>, 
  variable = 0x9e9ffffffffb8ff <Address 0x9e9ffffffffb8ff out of bounds>}
10: alias = (struct user_cmd *) 0x7ffff7ac675f
9: &argument[0][2] = <error: Cannot access memory at address 0x21>
8: &argument[0][1] = <error: Cannot access memory at address 0x21>
7: &argument[0][0] = <error: Cannot access memory at address 0x21>
6: &argument[0] = (char **) 0x21
(gdb) next
40		argument = malloc(sizeof(char));
11: alias[0] = {name = 0x0, variable = 0x0}
10: alias = (struct user_cmd *) 0x602030
9: &argument[0][2] = <error: Cannot access memory at address 0x21>
8: &argument[0][1] = <error: Cannot access memory at address 0x21>
7: &argument[0][0] = <error: Cannot access memory at address 0x21>
6: &argument[0] = (char **) 0x21
(gdb) 
41		*argument = malloc(sizeof(char));
11: alias[0] = {name = 0x0, variable = 0x0}
10: alias = (struct user_cmd *) 0x602030
9: &argument[0][2] = 0x2 <Address 0x2 out of bounds>
8: &argument[0][1] = 0x1 <Address 0x1 out of bounds>
7: &argument[0][0] = 0x0
6: &argument[0] = (char **) 0x602050
(gdb) 
42		*(argument + 1) = malloc(sizeof(char));
11: alias[0] = {name = 0x0, variable = 0x0}
10: alias = (struct user_cmd *) 0x602030
9: &argument[0][2] = 0x602072 ""
8: &argument[0][1] = 0x602071 ""
7: &argument[0][0] = 0x602070 ""
6: &argument[0] = (char **) 0x602050
(gdb) print &argument[0][1000]
$15 = 0x602458 ""
This causes problems later since I try and allocate memory to one of the pointers inside the struct and malloc gives it the same address as one of the argument pointers that has already been allocated. They then share the same value and any change made to one affects the other. How do I allocate memory to just the section I want within the double pointer without allocating everything under the sun?
 

usea

Member
Start by writing your plan of attack as comments. Really general at first, something like:
// read sentence from file
// establish translation from sentence
// read the rest
// ... and decode using translation

Then keep drilling down and breaking down each part, writing more comments/pseudocode, until it starts to feel silly and it's simpler to just write the code in a given section rather than spell things out further.

When you start writing actual code, try to do it in order. Try to establish the beginning of your code compiles and works correctly (using debug printing or whatever) before moving to the next part and building on it.
This is good advice. Better than I could have put it.
 

Water

Member
Ok, so the program I've been working on (C) for a while has had this memory-leakesque type problem wherein one of the values in my structs has been sharing a memory location with a pointer I malloced.
...
This causes problems later since I try and allocate memory to one of the pointers inside the struct and malloc gives it the same address as one of the argument pointers that has already been allocated. They then share the same value and any change made to one affects the other. How do I allocate memory to just the section I want within the double pointer without allocating everything under the sun?
I find that gdb barf incredibly hard to read. Would have been better to at least have the code in addition to it.

But if I'm guessing the types correctly, it looks as if you are only reserving enough memory for chars when you are supposed to reserve enough memory for pointers?
 

Ambitious

Member
I received my copy of Real World Haskell last week. Damn, this book is huge. And I haven't even finished Seven Databases in Seven Weeks and not even started Scala for the Impatient.. a lot of work to do. And "Memorize Sublime Text shortcuts" has been on my todo list for weeks now. Sigh.
 
A good place to start would be to actually read in the files and prepare the data for what you want to do. Next you can loop over the numbers and build the "decoded" string with them.

Start by writing your plan of attack as comments. Really general at first, something like:
// read sentence from file
// establish translation from sentence
// read the rest
// ... and decode using translation

Then keep drilling down and breaking down each part, writing more comments/pseudocode, until it starts to feel silly and it's simpler to just write the code in a given section rather than spell things out further.

When you start writing actual code, try to do it in order. Try to establish the beginning of your code compiles and works correctly (using debug printing or whatever) before moving to the next part and building on it.

These are good suggestions, thanks guys! My professor is making sure we write down comment blocks for each method of what their purpose is and what they're meant to accomplish, so I figure that'll play into it too. Like I said, the tough part for me is the beginning, and I'm sure as I learn more/get back into it, I'll do better. I also plan on going to my professor during his office hours tomorrow, so that should help too.
 
I find that gdb barf incredibly hard to read. Would have been better to at least have the code in addition to it.

But if I'm guessing the types correctly, it looks as if you are only reserving enough memory for chars when you are supposed to reserve enough memory for pointers?
Haha sorry and thanks for the honesty. I thought the debugger would have more important information than the actual source code for my question. Here's the source snippet:
Code:
        alias = malloc(sizeof(struct user_cmd));

        argument = malloc(sizeof(char));
        *argument = malloc(sizeof(char));
Alias is a user_cmd pointer and argument is a char double pointer. Problem is for *argument it allocates memory for *(argument + 0) to *(argument + 1000) and beyond.
 

Water

Member
Haha sorry and thanks for the honesty. I thought the debugger would have more important information than the actual source code for my question. Here's the source snippet:
Code:
        alias = malloc(sizeof(struct user_cmd));

        argument = malloc(sizeof(char));
        *argument = malloc(sizeof(char));
Alias is a user_cmd pointer and argument is a char double pointer. Problem is for *argument it allocates memory for *(argument + 0) to *(argument + 1000) and beyond.
It's like I said in the last post, you aren't reserving enough memory for your pointers and then all kinds of crazy stuff will happen. If this is a two-dimensional array, what you are looking for is something like
Code:
char** two_dim_array = malloc(sizeof(char*) * how_many_rows);
for (unsigned i = 0; i < how_many_rows; ++i)
    two_dim_array[i] = malloc(sizeof(char) * how_many_columns);
 
It's like I said in the last post, you aren't reserving enough memory for your pointers and then all kinds of crazy stuff will happen. If this is a two-dimensional array, what you are looking for is something like
Code:
char** two_dim_array = malloc(sizeof(char*) * how_many_rows);
for (unsigned i = 0; i < how_many_rows; ++i)
    two_dim_array[i] = malloc(sizeof(char) * how_many_columns);
Thank you for the help. It's hard for me to conceptualize pointers and arrays sometimes. This also helped me track down the original problem I was having so your help solved two problems in one!
 
Is it possible to pass a value by reference in C? And if not, is there an alternate method/workaround?

Pass it as a pointer. You're passing the value of the address of the value (say it 5 times fast!) to the function, but that's about as close as you can get.

Code:
void foo(int* v)
{
    *v = 10;
}

int main(void)
{
    int x= 0;
    foo(&x);
    printf("x = %d\n", x);
}

Should print as 10, effectively passing by reference.
 

Onemic

Member
Pass it as a pointer. You're passing the value of the address of the value (say it 5 times fast!) to the function, but that's about as close as you can get.

Code:
void foo(int* v)
{
    *v = 10;
}

int main(void)
{
    int* x= 0;
    foo(&x);
    printf("x = %d\n", x);
}

Should print as 10, effectively passing by reference.

When I try running the code as is, it keeps giving me an error at the foo function call(specifically the '&') stating that "argument of type int ** is incompatible with parameter of type int *"
 
When I try running the code as is, it keeps giving me an error at the foo function call(specifically the '&') stating that "argument of type int ** is incompatible with parameter of type int *"

oops. should be int x = 0 not int* x = 0. Sorry.

I just wrote it free hand and didn't test it. Whoops.
 

Onemic

Member
oops. should be int x = 0 not int* x = 0. Sorry.

I just wrote it free hand and didn't test it. Whoops.

Thanks.

I guess here is where the real question comes in. I want to make a for loop that takes a variable and multiplies it by 10, but takes the variable by reference so that the variable won't stay the same after each successive loop. (ie loop1: 10, loop2: 100, loop3: 1000, etc.) As I have it set up right now, since the variable is copied, the for loop will always take take the initial variable value and multiply it by 10 instead. so instead of the example above, I get: loop1: 10, loop2: 10, loop3: 10, etc. Using the method you provided above would it be possible to do this?
 
Ok, talked to my professor today, and he gave me some help with some stuff to keep in mind/regard for this assignment.

So basically, I use Scanner keyboard = new Scanner(System.in); to mimic a keyboard but really it's meant to automatically call in my text files, secretText1, secretText2, and secretText3.

So that I'm a bit confused on, I feel like I have it right (at least considering my professor saying that that part was on the right track except I was prompting for user to enter text when we don't need that so I took that out) but at the same time, I feel like I'm not 100% sure on that part.

And then I'm initializing a String for the key-phrase I need to get after closing the inputFile (again, no clue if this is right or wrong), and then trying to use charAt() after that... basically, I'm *sorta* getting somewhere with this assignment, but still feel like I'm pretty far off.

If someone could help me with these things in any way at all, that would be super awesome and helpful, thanks.
 
Thanks.

I guess here is where the real question comes in. I want to make a for loop that takes a variable and multiplies it by 10, but takes the variable by reference so that the variable won't stay the same after each successive loop. (ie loop1: 10, loop2: 100, loop3: 1000, etc.) As I have it set up right now, since the variable is copied, the for loop will always take take the initial variable value and multiply it by 10 instead. so instead of the example above, I get: loop1: 10, loop2: 10, loop3: 10, etc. Using the method you provided above would it be possible to do this?

Yep. That will work. You're still adjusting (read multiply in this case) the value stored at the address you passed to the function. So something like *x = *x * 10 (or succinctly *x *= 10. It's never going to be very pretty) should work.

If you want to see it working, print out the value of x (don't forget to dereference it when printing it!) and then print out the address at each step. The address won't change but the value will. Your compiler will probably give you a warning yelling at you for not dereferencing when printing the address but it should still run.
 

spootime

Member
Hey guys,

I'm interested in learning programming and based off my research so far I've chosen Python as my first language. I've been attempting to teach myself with THIS. I am also signed up for an introductory python class on coursera. I have a few questions:

1. Would you recommend starting with python? I eventually want to be able to code my own game as a long term goal.
2. The coursera course that I've signed up for seems to use Python 2.7, while I've been teaching myself so far on Python 3.3. Is this a big deal? Should I favor one over the other as a starter?
3. I see Learn Python the Hard Way recommended a lot, but from my understanding it teaches 2.7 and not 3.3. Again, should I just use that instead of the wikibooks link I provided?
4. Are there any other resources you guys would recommend?

Thanks in advance, I appreciate the help.
 

tr4656

Member
Hey guys,

I'm interested in learning programming and based off my research so far I've chosen Python as my first language. I've been attempting to teach myself with THIS. I am also signed up for an introductory python class on coursera. I have a few questions:

1. Would you recommend starting with python? I eventually want to be able to code my own game as a long term goal.
2. The coursera course that I've signed up for seems to use Python 2.7, while I've been teaching myself so far on Python 3.3. Is this a big deal? Should I favor one over the other as a starter?
3. I see Learn Python the Hard Way recommended a lot, but from my understanding it teaches 2.7 and not 3.3. Again, should I just use that instead of the wikibooks link I provided?
4. Are there any other resources you guys would recommend?

Thanks in advance, I appreciate the help.

1. Learning Python as your first language is fine.
2. There are definitely some differences between Python 2 and Python 3 but it shouldn't really matter for you. There are less modules that are in Python 3 but the popular ones are ported (or being ported) or there are alternatives. It sounds like all of these things you are using are 2.7 though, so starting with 3 may be a problem?
3. Sure, if you want to do Python 2.
4. Here are some python 3 resources: Invent with Python and Dive Into Python 3. Both of these are fine for beginners.
 

phoenixyz

Member
2. The coursera course that I've signed up for seems to use Python 2.7, while I've been teaching myself so far on Python 3.3. Is this a big deal? Should I favor one over the other as a starter?
Imo just learn Python 2 at first. It's more widespread and more modules and libraries are available. Especially considering the course you are doing is using Python 2.
 
Hello,

I'm currently running across a problem in my homework. To make things brief, is it possible to multiply, subtract or divide char in c++?

Right now I can add by doing let's say:

char a = '5';
char b = '7';
char c = ((a-0) + (b-0))

Using any other operator but addition results in an incorrect number.

The larger scope of the problem is that we're dealing with stacks, I understand how to pop and push stacks, the issue is we're performing operations on things like this:

((5-1)/2)*(2+5);

so it will store faulty numbers because we're using char to perform operations and store it back into the stack.

The other question I had, is if a integer is over 9 then I can't store it as char can I?

Is this most likely an oversight by the professor is there something I'm missing here?

To clarify, he already wrote the stack class and defined ItemType to be a char type (instead of a new class).
 

arit

Member
Hello,

I'm currently running across a problem in my homework. To make things brief, is it possible to multiply, subtract or divide char in c++?

Right now I can add by doing let's say:

char a = '5';
char b = '7';
char c = ((a-0) + (b-0))

Using any other operator but addition results in an incorrect number.

The larger scope of the problem is that we're dealing with stacks, I understand how to pop and push stacks, the issue is we're performing operations on things like this:

((5-1)/2)*(2+5);

so it will store faulty numbers because we're using char to perform operations and store it back into the stack.

The other question I had, is if a integer is over 9 then I can't store it as char can I?

Is this most likely an oversight by the professor is there something I'm missing here?

To clarify, he already wrote the stack class and defined ItemType to be a char type (instead of a new class).

You can do that, but it will use just the numerical value of that char, ie. '8' = 56 and '2' = 50 and '8'/'2' = 56/50 = 1. So while you can do those operations, you will not get your "expected" result. To do that you first have to convert it, if you are just using single digits char var - '0' would be sufficient, for strings you could use something like atoi().
 
You can do that, but it will use just the numerical value of that char, ie. '8' = 56 and '2' = 50 and '8'/'2' = 56/50 = 1. So while you can do those operations, you will not get your "expected" result. To do that you first have to convert it, if you are just using single digits var - '0' would be sufficient, for strings you could use something like atoi().

Unfortunately it won't be feasible for this situation, he has input data that tests all sorts of things. So honestly not sure what to do, I can get it to compile but the end result won't be what he's looking for. I think its an oversight on his part, he sometimes makes mistakes like these.
 

Slavik81

Member
Hello,

I'm currently running across a problem in my homework. To make things brief, is it possible to multiply, subtract or divide char in c++?

Right now I can add by doing let's say:

char a = '5';
char b = '7';
char c = ((a-0) + (b-0))

Using any other operator but addition results in an incorrect number.

You need to decide what your numbers mean. If they are ascii symbols like '5' and '7', you'll need to convert them to their numeric value before performing math operations on them. Then you can convert back.

Unfortunately it won't be feasible for this situation, he has input data that tests all sorts of things. So honestly not sure what to do, I can get it to compile but the end result won't be what he's looking for. I think its an oversight on his part, he sometimes makes mistakes like these.
I can't imagine how this could be a problem. The fact that there are tests is a good thing. They state with perfect clarity what is expected of your program.
 
There's nothing inherently wrong with test data, if I'm understanding what you're saying is that you want me to convert it to actual integers, evaluate, convert back and store it into the stack.

Here is my code, the output is still incorrect. I'mt not asking for anyone to do the coding for me, I'm trying to understand why I'm getting the output that I am.


inFile is datatype ifstream, outFile is ofstream, ina, inb, and inc are all char.

if (evalFlag == true)
{

eqStack.MakeEmpty(); //makes the stack empty
inFile.open("in.data");


inFile >> ina; //priming read

while(inFile) //loop until EOF
{
if (ina == ';') //the ; signifies the end of input
{
eqStack.Pop(inc);
eqStack.Pop(inb);
eqStack.Pop(ina);

if (inb == '+')
eqStack.Push((ina - '0') + (inc - '0')); // I believe I'm storing the sum of
else if (inb == '-') //of these numbers into the stack
eqStack.Push((ina - '0') - (inc - '0')); //which will convert them back into
else if (inb == '*') //char
eqStack.Push((ina - '0') * (inc - '0'));
else if (inb == '/')
eqStack.Push((ina - '0') / (inc - '0'));

eqStack.Pop(ina);

outFile << "~~ Evaluation Result is " << ina - '0' << endl << endl;
break;
}
else if (ina == ')') //basically a repeat of above code but reads in next input
{
eqStack.Pop(inc);
eqStack.Pop(inb);
eqStack.Pop(ina);

if (inb == '+')
eqStack.Push((ina - '0') + (inc - '0'));
else if (inb == '-')
eqStack.Push((ina - '0') - (inc - '0'));
else if (inb == '*')
eqStack.Push((ina - '0') * (inc - '0'));
else if (inb == '/')
eqStack.Push((ina - '0') / (inc - '0'));

inFile >> ina;
}

else if (ina == '(') //ignores left parenthesis, reads next character
inFile >> ina;

else
{
eqStack.Push(ina);
inFile >> ina;
}


}

Thanks for your help.
 

arit

Member
Your stack consists of chars representing numbers, you then pop an X OP Y expression from the stack. You convert those characters to integer numbers through X -'0' and Y - '0', so you can use your OP. But after getting your calculations done, you have to reconvert that integer value back to char if the result is to be pushed back on the stack.

But this whole using chars on the stack seems rather limited, what if you get negative numbers or, as you've noticed before, values >9?.
 
Your stack consists of chars representing numbers, you then pop an X OP Y expression from the stack. You convert those characters to integer numbers through X -'0' and Y - '0', so you can use your OP. But after getting your calculations done, you have to reconvert that integer value back to char if the result is to be pushed back on the stack.

But this whole using chars on the stack seems rather limited, what if you get negative numbers or, as you've noticed before, values >9?.

Yeah that's what I figured.

Dunno he wrote the specification and implementation files himself, we just have to write client code. It's wierd because I perfectly understand stacks, its just this is what I have to get past. I'm probably just going to compile it and turn it in, if enough students have issues I'm sure he'll do something.

Again thanks you all for replying. Thinking of making a stackoverflow account as well :p.
 

Onemic

Member
Thanks, Notrollious for the advice earlier. It worked wonders.

I finally finished writing my program. Just wondering if any of you guys could give comments on how to improve my codes general readability, comments, and code formatting/etiquette, because I'm kind of lost on where to improve on that front.

This is in C btw.

Code:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int SINnum;
int SINnumCheck;
int alternateNum;
int alternateNum1;
int i;
int n;
int turnOff = 1;
int a = 1;
int b = 10;
int a1 = 10;
int b1 = 1;
int alt1;
int altStore1;
int altStore2 = 0;
int altStore3;
int altStore4 = 0;
int total;
int difference;

//calculates difference between total and next highest multiple of 10
void checkTotal(){ 
    difference = total % 10;
    difference = 10 - difference;
}

//gets first set of alternate numbers
void getAltNum1(int* v, int* x)
{
    if(turnOff == 1){
        *v = *v * 100;
        alternateNum = (SINnum % *v) / 10;
        turnOff = 0;
    } else {
        *v = *v * 100;
        *x = *x * 100;
        alternateNum = (SINnum % *v) / *x;
    }
}

//gets second set of alternate numbers and calculate sum of getAltNum2
void getAltNum2(int* v, int* x)
{
    *v = *v * 100;
    *x = *x * 100;
    alternateNum1 = (SINnum % *v) / *x;
    altStore3 = alternateNum1;
    altStore4 = altStore4 += altStore3;
}

//adds first set of alternate numbers and gets sum of alternate numbers in getAltNum1
void altNum1Result(int* alt){
    *alt = alternateNum + alternateNum;
    if(*alt > 9){
        *alt = 1 + (*alt % 10);
        altStore1 = alt1; 
        altStore2 = altStore2 += altStore1; //stores sum of alternate single digits
    } else {
        altStore1 = alt1; 
        altStore2 = altStore2 += altStore1; //ensures store is only used when needed
    }
}

int main() {
    printf("SIN VALIDATOR\n");

    printf("\nEnter SIN(Enter 0 to quit)\n");
    scanf("%d", &SINnum);
    if(SINnum != 0){
    SINnumCheck = SINnum % 10;
    printf("Check Digit = %d\n", SINnum%10);

    for(i = 0; i < 4; i++){
        getAltNum1(&a, &b);
        printf("alternate nums are: %d\n", alternateNum);
        altNum1Result(&alt1);
        printf("adding %d + %d: %d\n", alternateNum, alternateNum, alt1);
        printf("The sum for these numbers are: %d\n", altStore2);
        if(i >= 3){
            for(n = 0; n < 4; n++){
                getAltNum2(&a1, &b1);
                printf("2nd set of alternate nums are: %d\n", alternateNum1);
                printf("The sum for these numbers are: %d\n", altStore4);
            }
            total = altStore2 + altStore4;
            checkTotal();
            printf("The total for these numbers are: %d\n", total);
            printf("The difference between the total and next highest integer of 10 is: %d\n", difference);

            if(difference == SINnumCheck){
                printf("SIN number is valid\n");
            } else {
                printf("SIN number is not valid\n");
            }
        }
    }
//resetting all referenced variables to their default values
    turnOff = 1;
    a = 1;
    b = 10;
    a1 = 10;
    b1 = 1;
    alt1;
    altStore1;
    altStore2 = 0;
    altStore3;
    altStore4 = 0;
    main();
    } else {
        printf("Have a nice day\n");
    }

//dummy code to stop console from autoclosing when done
    {
    int dummy;
    scanf("%d", &dummy);
    }
    return 0;
}

Forgive some of the odd printf wording. I was real tired making this.
 

Water

Member
I finally finished writing my program. Just wondering if any of you guys could give comments on how to improve my codes general readability, comments, and code formatting/etiquette, because I'm kind of lost on where to improve on that front.
Two obvious improvements:

Stop using global variables. Everything between int SINnum; and int difference; needs to either be inside a function, or turned into constants.

Don't call main() recursively inside an if statement. Instead, put in a loop that keeps going as long as you need to.
 

tokkun

Member
As Water stated, you should avoid using global variables in programs.

The other general comment I would make is that for something like

Code:
void altNum1Result(int* alt)

where the value being modified is relatively simple, I would suggest returning a value rather than passing a pointer and mutating the value referenced by the pointer. That is to say, I prefer to see something like this:

Code:
int altNum1Result()

I would similarly recommend that you change your functions that modify 2 ints to return a struct containing the two ints rather than modifying the pointers (if this were C++ you could return std::pair or std::tuple instead of having to create a struct).

Code:
typedef struct {
  int x;
  int v;
} altNumPair;

...

altNumPair getAltNum1(altNumPair current) { ... }

Basically there are two separate ideas at play with that recommendation.

1. Programmers are more prone to mistakes when working with pointers (ex: forgetting to dereference) and pointers are dangerous when used incorrectly (ex: memory corruption, SIGSEGV). You also do not have to worry about what happens if NULL is passed.

2. There are a couple of issues related to the use of functions and manipulation of state. There is an argument underlying functional programming that it is preferable to have functions to treat their arguments as immutable and not alter any non-local state in the program - this is part of the reason why global variables are discouraged, since they always violate this tenet.

Neither of these are hard-and-fast rules, but they are things that I think it is generally good to try to adhere to when feasible. Realistically there will be cases where you have to use pointers and cases where it is cleaner to use a function to modify non-local state.
 
Alright ProgrammingGAF my group and I were recently assigned a program wherein we have to basically mimic malloc, realloc and calloc. He wants us to start off by declaring an array at the beginning of the program and then using that as the "memory source" for all our extra data to be created. Since we're using C we can declare the array as a type (not void) but how do we then convert it to another type? I've seen mention of type punning but we're not really sure where to go. Any help?
 

Tamanon

Banned
hey guys I need help with my tictactoe game. My checkwin function seems to not be working. The game keeps playing even after there is 3 in a row.

checkwin: http://pastebin.com/FJb0u5pP

main:http://pastebin.com/Ah8PDx9a

If you guys need any other functions posted let me know.

Code:
else if(whoWon != 'X' || whoWon != 'O')
Shouldn't that be....

Code:
else if(whoWon != 'X' && whoWon != 'O')

Because you're saying if it's not X OR it's not O....which if it's X, it's not O.
 

tokkun

Member
Alright ProgrammingGAF my group and I were recently assigned a program wherein we have to basically mimic malloc, realloc and calloc. He wants us to start off by declaring an array at the beginning of the program and then using that as the "memory source" for all our extra data to be created. Since we're using C we can declare the array as a type (not void) but how do we then convert it to another type? I've seen mention of type punning but we're not really sure where to go. Any help?

Declare the array as char[] so it is byte-addressable. Cast the pointer as void* when returning it.
 
Declare the array as char[] so it is byte-addressable. Cast the pointer as void* when returning it.
Why does C allow the cast to be changed to void but not any other data type? If the answer is too long is there maybe a resource you could point me to so I could learn?
 

Blizzard

Banned
Why does C allow the cast to be changed to void but not any other data type? If the answer is too long is there maybe a resource you could point me to so I could learn?
You can cast a pointer to other data types, but malloc/calloc/realloc return void pointers, so that's what your imitation functions presumably have to return.

I don't know whether your assignment means you have to support multiple allocations within the byte region or not -- depends how advanced the class is.
 

Onemic

Member
Two obvious improvements:

Stop using global variables. Everything between int SINnum; and int difference; needs to either be inside a function, or turned into constants.

Don't call main() recursively inside an if statement. Instead, put in a loop that keeps going as long as you need to.

How do I call(is that the right term?) a variable that's been defined locally in a function though? Right now if I put some of those variables I defined as global in their appropriate functions and tried to call them, I would get an error.

How would I make the loop? Would I wrap the main components of the program in a function?

As Water stated, you should avoid using global variables in programs.

The other general comment I would make is that for something like

Code:
void altNum1Result(int* alt)

where the value being modified is relatively simple, I would suggest returning a value rather than passing a pointer and mutating the value referenced by the pointer. That is to say, I prefer to see something like this:

Code:
int altNum1Result()

I would similarly recommend that you change your functions that modify 2 ints to return a struct containing the two ints rather than modifying the pointers (if this were C++ you could return std::pair or std::tuple instead of having to create a struct).

Code:
typedef struct {
  int x;
  int v;
} altNumPair;

...

altNumPair getAltNum1(altNumPair current) { ... }

Basically there are two separate ideas at play with that recommendation.

1. Programmers are more prone to mistakes when working with pointers (ex: forgetting to dereference) and pointers are dangerous when used incorrectly (ex: memory corruption, SIGSEGV). You also do not have to worry about what happens if NULL is passed.

2. There are a couple of issues related to the use of functions and manipulation of state. There is an argument underlying functional programming that it is preferable to have functions to treat their arguments as immutable and not alter any non-local state in the program - this is part of the reason why global variables are discouraged, since they always violate this tenet.

Neither of these are hard-and-fast rules, but they are things that I think it is generally good to try to adhere to when feasible. Realistically there will be cases where you have to use pointers and cases where it is cleaner to use a function to modify non-local state.

I'll try those suggestions, thanks.


I also have another problem thats been bugging me for a few weeks. I created a program about 3 weeks back that plays a variation of rock paper scissors and when the user is done playing the program shows the statistics of the game. Games played, player 1 wins, player 2 wins, tie games, and winning percentages for both players. Problem is, I can't get the winning percentages to display properly and I have no idea what I'm doing wrong. Initially I made it a function and then just made it a simple variable, but it's still not displaying the correct values. Here's the code(the defined variables for winning percentage, 'score1' and 'score2' are at the bottom. Since I made this weeks ago, I still have a ton of global variables, heh.

EDIT: got it now
 

tokkun

Member
How would I make the loop? Would I wrap the main components of the program in a function?

You want to repeat a process until a certain condition is met. Therefore you should use a while loop.

Code:
scanf("%d", &SINnum);
while (SINnum != 0) {
  ...
  scanf("%d", &SINnum);
}

or

Code:
while (true) {
  scanf("%d", &SINnum);
  if (SINnum == 0) break;
  ...
}

or if you care about compactness, you can do the same thing with a for loop


Code:
for(scanf("%d", &SINnum); SINnum != 0; scanf("%d", &SINnum)) {
  ...
}
 

arit

Member
I also have another problem thats been bugging me for a few weeks. I created a program about 3 weeks back that plays a variation of rock paper scissors and when the user is done playing the program shows the statistics of the game. Games played, player 1 wins, player 2 wins, tie games, and winning percentages for both players. Problem is, I can't get the winning percentages to display properly and I have no idea what I'm doing wrong. Initially I made it a function and then just made it a simple variable, but it's still not displaying the correct values. Here's the code(the defined variables for winning percentage, 'score1' and 'score2' are at the bottom. Since I made this weeks ago, I still have a ton of global variables, heh.

Code:
#define _CRT_SECURE_NO_WARNINGS
        score1 = (player1Score / gamesPlayed) * 100;

Since player1Score and gamesPlayed are still ints, they get evaluated as such.
You could cast within the calculation
Code:
        score1 = ((double)player1Score / gamesPlayed) * 100;
or if an int score would be sufficient just calculate as
Code:
        score1 = (player1Score * 100) / gamesPlayed;
 

Atruvius

Member
I have a little school assignment in java which includes reading from ini file. I have tried googling how reading ini files work in java work but couldn't really find what I was after.

The ini file includes has section which have keys. And user has to pick one of the sections and their keys and the program will output the key's value.
 

poweld

Member
I have a little school assignment in java which includes reading from ini file. I have tried googling how reading ini files work in java work but couldn't really find what I was after.

The ini file includes has section which have keys. And user has to pick one of the sections and their keys and the program will output the key's value.

I think all you're trying to do is read from a file. If so, look at: http://docs.oracle.com/javase/1.4.2/docs/api/java/io/Reader.html
 
Can someone help me with this? I'm supposed to compute the arithmetic expression 8x - 2y + 14 in assembly using left shifts. Everything seems to be working fine except that when try to load one of the values into a register it's reporting a different value

The first three ori's should load 1, 1, and 14 respectively into the registers. Then the next two left shifts act as basic multiplication , then I take the difference of the two registers store that in a new register and add that value and the value in register 7 (14 or well it should be 14) and that should be mathematically correct for computing that expression?
Code:
main:
        ori           $5,$0,0x1       
        ori           $6,$0,0x1  
	ori 	      $7,$0,0xE
	sll 	      $5, $5,3
	sll 	      $6, $6,1
	subu 	      $8, $5,$6
	addu 	      $10, $7,$8
Here's the problem
Edited to reflect current problem
Code:
main:
[0x00400000]	0x34050001  ori $5, $0, 1                   ; 12: ori   $5,$0,0x1       
[0x00400004]	0x34060001  ori $6, $0, 1                   ; 13: ori   $6,$0,0x1  
[0x00400008]	0x34070014  ori $7, $0, 14                  ; 14: ori   $7,$0,0xE
[0x0040000c] 	0x000528c0  sll $5, $5, 3                   ; 15: sll 	$5,$5,3
[0x00400010]	0x00063040  sll $6, $6, 1                   ; 16: sll 	$6,$6,1
[0x00400014]	0x00a64023  subu $8, $5, $6                 ; 17: subu 	$8,$5,$6
[0x00400018]	0x00e85021  addu $10, $7, $8                ; 18: addu 	$10,$7,$8
It seems to be loading 20 into register 7 instead of 14? I'm not sure why, any help would be appreciated.
 
0x14 = 20 is the issue if I had to guess. Try 0xE

Tried that but it showed R7 (a3) = 0000000e , which then threw off the addu call im guessing bc the value in R10 still isn't correct

Maybe something else is wrong, idk bc that is the correct bit pattern for 14, i just cant seem to get the R7 and R8 to sum correctly

(this is my first crack at assembly.. ever)

I should be getting R10 = 20 i believe 8*1 - 2*1 + 14 = 20 but im getting 14 in R10? And registers 5 and 6 are recording the correct results for a left shift, register 8 is holding the correct difference, i just cant seem to get R10 to correctly hold the sum of R7 and R8

I haven't touched assembly in 5 or 6 years, I just saw that you were trying to treat 0x14 as 14 and thought that changing it to 0xe might fix it for you. Sorry it didn't! Someone with more assembly knowledge might know what's up though.

Appreciate the help none the less :)
 
Top Bottom