Banfa 597 Posting Pro Featured Poster

MoveRect needs to be called on a rectangle object because it is now a class member Rect.MoveRect(10, 30);

Banfa 597 Posting Pro Featured Poster

now , this program is printing all the prime numbers < 15 ,

but it is printing them more than one time...why ? every prime number is printed there but since 9 is not a prime number why it is printed ?

No it doesn't for instance it prints 9 which is definately not prime.

You still have your print statement inside your inner loop. it needs to be outside your inner loop.

Banfa 597 Posting Pro Featured Poster

i already have my program to check that the input number is prime or not and your program is for the specific number while i want to calculate first 20 primes.
and here is what i've made but it is not working,

int main(void)
{
int a,b,c;
for (a=1;a<21;a++)
{
for (b=21;b>2;b--)
if (b<a)
{
c=a%b;
if (c==0)
break;
else
printf ("%d",a);
}
}
getche ();
}

You want to print the prime numbers, however the test for primality is not divisible by any integer less than itself except 1. That means you have to check every single integer (not true actually but in your simplistic algorithm it is) before you can be sure a number is prime. That means your print statement must be outside the inner loop and when you have exited that loop you need to be able to tell if the loop completed or if the break happened. If the break happened the number is not prime.

Also note your end condition for inner loop is wrong, you never check to see if a is divisible by 2. I think you may find that 4 is incorrectly identified as prime.

You say you want the first 20 primes but this actually calculates the number of primes <= 20, there will certainly not be 20 of them. The end condition for the outer loop should be on the number of primes found so far.

Xufyan commented: thankx..xufyan +0
Banfa 597 Posting Pro Featured Poster

lines 117 - 123, when I said re-write the function without the parameter and operate directly on the class members that did mean that you would have re-write the function to remove references to the parameter aRect and instead use references to the member variables of the class, not that you could just change the function declaration.

Re-write the function using member variables just as all the other class member functions are using member variables.

Banfa 597 Posting Pro Featured Poster

don't move the } at line 93 just change line 92 from friend void MoveRect(Rectangle& aRect, int x, int y); to void MoveRect(int x, int y);

Banfa 597 Posting Pro Featured Poster

Line 115 re-write

// Friend function to move rectangle
void MoveRect(Rectangle& aRect, int x, int y)
{
    ... function code snipped 
}

as

// Member function to move rectangle
void Rectangle::MoveRect(int x, int y)
{
    ... function code snipped 
}
Banfa 597 Posting Pro Featured Poster

if i were to make my function const then i would need to create a object of my number class in my function and then return that since in my function i am returning a Number & ?

All the non assigning operators, such as operator+ should return an object not a reference if they are to work correctly and handle memory correctly.

Banfa 597 Posting Pro Featured Poster

The problem is that the parameter number is const (constant) but you are trying to use it to call operator- which is not a const member function. number (const Number &) can not be converted to Number * in order to make the method call in return number.operator -(*this); and you get that error because of it.

However I think you have a more fundamental error because operator+ (and operator-) should not return *this, it should return a new object there should be no in-place alteration of the current object(this) under addition.

For example

int a = 5;
int b = 10;
int c;
c = a + b;

After running this code a = 5, b = 10 and c = 15 but

Number a = 5;
Number b = 10;
Number c;
c = a + b;

After running this code the way you have it written a = 15, b = 10 and c = 15 because Number::operator+ modifies the object it is called on.

Instead of creating operator+ I suggest you create operator+= also you should implement a copy constructor Number::Number(const Number&).

Then you can simply implement operator+ as

Number Number::operator+(const Number& rhs)
{
    return Number(*this) += rhs;
}

implement it inline and if you are lucky you will get a return code optimisation.

Banfa 597 Posting Pro Featured Poster

no you would remove the first parameter as well and operate directly on all the class members just like your other member functions.

Banfa 597 Posting Pro Featured Poster

One of the major differences is that floats get promoted to doubles when used as parameters in functions that have no declaration or in the variable parameter list of varidac functions (like printf). So printf never sees a float in the parameter list and does not need to differetiate between floats and doubles.

On the other hand scanf deals with pointers to data types and a pointer to float and a pointer to double are to very different beasties so scanf must be informed which one to expect.

A similar thing happens with short and int. shorts are automatically promoted to int in the same situation so printf does not need to know if you are passing a short or int to it %D does for both. I know that %hd exists for printf but if you read around you will find some places that correctly say "causes printf to expect a int sized integer argument which was promoted from a short".

I am not quite sure why printf would need this information but at least then the same format string can be used for printf and scanf. However again calling scanf it is imperative that %hd is used for short and %d for int because again short * and int * are quite different.

Banfa 597 Posting Pro Featured Poster

Like the error says you can not use the friend keyword in a managed type (manged C++ has delegates and events to get round that).

Why can you just make your MoveRect function a class member?

Banfa 597 Posting Pro Featured Poster

<pedantic>
Most of the above posts make the following assumptions

  1. 'B' - 'A' == 'C' - 'B' == ... == 'z' - 'y' == 1 and similarly for all letters that are adjacent in the alphabet.

  2. 'a' - 'A' == 'b' - 'B' == ... == 'z' - 'Z' and similarly for all lower case upper case letter pairs in the alphabet.

These relationships between the numeric values of letters are not a function of C (or C++) but rather a function of the execution character set in use, in this case ASCII. The C standard does not require the use of ASCII as the execution character set or in fact any particular character set and does not require the relationships 1 and 2 above. It does require that

'1' - '0' == '2' - '1' == '3' - '2' == '4' - '3' == '5' - '4' ==
'6' - '5' == '7' - '6' == '8' - '7' == '9' - '8' == 1

There are some character sets where the letters do not have contiguous character values EBCDIC is the example normally given where 'J' - 'I' == 8.

While a very large number of today's platforms use ASCII as their compilation and execution character set there are still some platforms (mobile phones spring to mind, or at least the SMS parts of them) that don't.

It is normally easy enough to get round this …

Banfa 597 Posting Pro Featured Poster

Code::Blocks is just a light IDE that calls out to gcc so you can just put the compiler switch I gave in post #24 onto you command line

Banfa 597 Posting Pro Featured Poster
int number = 65;
char letter = number;

There are no characters in C only integers with different ranges. A character is no more than a number that is interpreted by the display sub-systems to write pixels on the screen in a forum that you recognise as a letter.

Banfa 597 Posting Pro Featured Poster

I do not know exactly what that function does.

That function does not return a buffer, it accepts a buffer (well 2 buffers really, lpBuf and lpKey) and a parameter (again 2 really for the size of each of the buffers) that by convension is the length of the buffer.

Convention is that the parameter passed in dwBufLen is the length of the buffer pointed to by lpBuf. However that is entirely dependent on the calling code, there is nothing to prevent the calling code (which you don't show) passing a pointer to a buffer that is longer than dwBufLen. However whatever the actual length of the buffer that function on works on the first dwBufLen BYTEs of it.

If that function is doing any compressing then is is compressing the data in lpKey into lpBuf. However the function does not change the size of either of the buffers lpKey and lpBuf.

Banfa 597 Posting Pro Featured Poster

Just put an if statement round the contents of the inner loop testing the condition a != b

BTW the is little point doing the calculation for b == 1 because a % 1 == 0 for all a.

Banfa 597 Posting Pro Featured Poster

You've missed the braces { } round the 2 lines of code that should be in the inner loop so that the printf statement is only executed once for every iteration of the outer loop.

Banfa 597 Posting Pro Featured Poster

No I am sure that that function doesn't alter the buffer length and that even if it did that would have no effect on the buffer length in the calling code.

I know that convention is that a parameter like dwBufLen is the length of the buffer but I can not be sure that that convention is followed in the code you have posted.

Banfa 597 Posting Pro Featured Poster

In that case you will need to post the smallest sample of code that compiles and still produces the error or at the very least all the definitions of all the symbols you are using.

Banfa 597 Posting Pro Featured Poster

That function does not change the size of the buffer pointed to by lpBuf, actually it can't because lpBuf is passed by value.

The code of the function implies that dwBufLen must be <= the size of the buffer pointed to by dwBufLen.

You should consult the creator of this function or the creater of the code that calls this function to find out for sure if the meaning and use of dwBufLen is the length of the buffer pointed to by lpBuf; although by normal convention it would be.

Banfa 597 Posting Pro Featured Poster

You are missing the ) at the end of the function parameter list.

Banfa 597 Posting Pro Featured Poster

Yes really.

Of course sizeof(*lpBuf) wont work. lpBuf has type LPBYTE (pointer to a BYTE) so *lpBuf has type BYTE so sizeof(*lpBuf) is sizeof(BYTE) which is most likely 1.

Of course you can get a pointer to the last element in the buffer, just calculate it from the start pointer and the buffer size.

Banfa 597 Posting Pro Featured Poster

LPBYTE is a pointer to a BYTE. If you have allocated an array of BYTEs and pointed lpBuf at that allocated array then if you need the size of that buffer you have to store it somewhere.

There is no function you can call that will return the size of an array that you are accessing through a pointer.

Banfa 597 Posting Pro Featured Poster

second can be used as a function if it is declared as a function pointer.

//For a map declared like this
    map<string, void(*)(void)> funTable;    // Actually not that much fun

// You can call the function through the iterator in any of these 3 ways
    iter->second();
    (iter->second)();
    (*iter->second)();
Banfa 597 Posting Pro Featured Poster

Note that generating a random number between 1 and N using rand() % N + 1 for small N is a poor solution because rand() often has very poor randomness in the low order bits of its return value.

read this

Rather than float pctRoll = (float) (rand() % 1000) / 1000.0; why not float pctRoll = (float)rand() / ((float)RAND_MAX + 1); which produces a similar result range but uses the entire return range (i.e. all bits) of rand().

Also the advice I here nowadays is that you should generally use double unless you have a specific comunicable reason to use float.

So double pctRoll = (double)rand() / ((double)RAND_MAX + 1);

Banfa 597 Posting Pro Featured Poster

It looks to me like what you need is an STL map

Banfa 597 Posting Pro Featured Poster

You have only forward declared Vistor in this code snippet so it does compile at line 26 which requires the full declaration of visitor.

Assuming this is a mistake that doesn't exists in your actual code and the the missing ; on line 33 is a typo then have you declared any Virtual functions in visitor? You can only dynamic_cast from a class with virtual functions defined in it. Note that any class in a hierarchy like this one should have its destructor declared virtual at a minimum.

If I put in a ; on line 33 and replace class Visitor; with

class Visitor
{
public:
    virtual ~Visitor(){}
};

it compiles for me.

Banfa 597 Posting Pro Featured Poster

A-ha. When I compile that code I get these errors

main.c|9|warning: assignment makes pointer from integer without a cast|
main.c|11|warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘int *’|

It might have beed a good idea to let us know that the "assignment makes pointer from integer" warning was not actually on the line of code that called malloc or calloc.

The malloc and calloc calls in this code are completely fine. I leave as an exercise for you (initially) to work out what is wrong on the indicated lines 9 and 11.

Banfa 597 Posting Pro Featured Poster

You have no ; at the end of your class IntList

Banfa 597 Posting Pro Featured Poster

Basically you can't integrate that cast. You can do something convoluted using the visitor design pattern that ends up calling a method on Horn with a pointer to Alarm but I am not sure that that is any better than just doing a dynamic cast.

You could create a template function in Observer to do the cast but that is barely any better than just calling dynamic_cast directly.

You have the generic solution.

Many concrete observers (Horn in your case) maintain a reference to the concrete subject they are observing, after all often observers wish to access subjects at times other than when the subject is updated. This reference can have the concrete type so have access to the subjects public interface. The pointer passed in notify is just used to verify that the update is about the specific object the observer is interested in.

In fact in this scenario passing the subject in the notify function can be omitted if there is a strict 1 to 1 (or many to 1) relationship between observer and subject.

Banfa 597 Posting Pro Featured Poster

Yes, for the N'th time, i am including stdlib.h

Sorry you are getting frustrated :-)

What can I say, the compiler error indicates that the compiler thinks that malloc returns int, that means that for some reason the compiler has not see the declaration of malloc possible reasons are

  • stdlib.h not included, either actually no #include statement or for some reason the #include statement is not being parsed

  • Include protection for stdlib.h defined before including stdlib.h
  • An edit in stadlib.h has removed the declaration of malloc
  • Something I can't think of.

However "assignment makes pointer from integer without a cast" is not an error that you should fix with a cast unless you are specifically expecting to have to convert an integer to a pointer.

If you post the compilable unit producing the error I will see if I can work out what it is.

Banfa 597 Posting Pro Featured Poster

The problem is that you class Subject has no virtual methods so has no vtable to allow the dynamic cast to happen.

The esiest way to solve this is to add a virtual deestructor virtual ~Subject() {}; to Subject. If you are going to sub-class from it and use base class pointers the destructor should be virtual anyway to ensure correct operation should you delete through the base class pointer.

Banfa 597 Posting Pro Featured Poster

In a strict sense the compiler compiles a translation unit it into an object form - and may not (doesn't have a right to) change any observable logic.

Ignoring the specific case in question this statement is wrong as a generalisation.

For instance the compiler is required to change the constant 0 when used in a pointer context into the platforms representation of the NULL pointer, which note is not required to be all bits 0.

The compiler is specificly required to change the observable logic in just the way you have claimed it has no right to.

Banfa 597 Posting Pro Featured Poster

That is not quite true, when the notify method is called it gets a Subject pointer to some object. You know that object can definitely not be a Subject because Subject is abstract and so can not be instantiated.

You have been passed a base class (Subject) pointer to a derived class (possibly an Alarm).

You can use the typeid operator or dynamic casting to determine the type of the object being pointed to. Obviously you will not be able to call any derived class functions through a base class pointer so some conversion may be required.

Banfa 597 Posting Pro Featured Poster

Firstly if cpu utilisation is only getting to 70% there is nothing to worry about. All programs are getting all the cpu time they require with time (30% of the available time) left over.

A single run of your program however only opens a single file and reads it, if you are talking about multiple files then you must be running the program multiple times. It is the operating systems responsibility to share processor time between process that need it even if some of those processes are demanding 100% of the cpu time the operating system will on the whole not them them have it.

If you are still worried then are are things you can do but they will slow down the operation of the program.

You could run the program at a lower priority. The priority is an attribute that the operating system uses when scheduling tasks, lower priority programs get less processor time. You can change the priority either programatically by making approriate function calls or by using a utility like nice (try "man nice") to run the program with a reduced priority.

You could interrupt the read loop in the program with a yield or a small sleep.

However I would recomend that you do neither of these until you get to the point where you computer is getting problems because it is running out of processing resource which is isn't currently, it still has 30% of that resource left.

Banfa 597 Posting Pro Featured Poster

Are you including stdlib.h?

If the compiler thinks that malloc returns int then it has not seen a prototype for malloc telling it it returns void*

This is exactly the problem with casting the return of malloc in C it hides this error which can lead to a non-funcaional program on a 64bit system.

Banfa 597 Posting Pro Featured Poster

You mean to say that return 0 means, by default, success (irrespective of platform). Hurray!
So, does all this means return EXIT_SUCCESS is redundant?

May be a little but good programming practices dictate that you use symbols with good semantic means rather than magic numbers.

My guess is that before standardisation EXIT_SUCCESS didn't exist and it was common to return 0 for success. At some point EXIT_SUCCESS was introduced to meet best practices of not using magic numbers but returning 0 had to be maintained as a success return for backwards compatibility.

People just continue to use 0 rather than EXIT_SUCCESS because it is rather easier to type.

Banfa 597 Posting Pro Featured Poster

Project -> Build options -> Select Project Name in List -> Compiler Settings Tab -> Other Tab -> Type it in


I wish I could work out why it seems to be defaulting to C++ though I'm not happy about forcing the compilers hand in this manner but rom the information you have provided I can't see what the problem is.

Banfa 597 Posting Pro Featured Poster

Since almost everything to do with bit fields is platform defined I would have no problem using extensions such as these.

The long and the short of it is if you want portable code don't use bit fields.

Banfa 597 Posting Pro Featured Poster

Just to clarify it is explicitly stated in the C standard that main if returns a value of 0 (or EXIT_SUCCESS) then the program will return a value to the system that indicates the program was successful.

Note that is not necessarily 0; if the system in question does not treat 0 as success then it is the compilers or the exit codes responsibility to interpret the 0 value returned from main and return the correct value to the system.

If you return 0 from main and the system thinks your program is returning an error then you are using a non-conforming compiler and should think about changing it.

Ancient Dragon commented: Sounds logical to me :) +27
Banfa 597 Posting Pro Featured Poster

for gcc thats easy add the compiler switch -x c

Banfa 597 Posting Pro Featured Poster

However, with my compiler at least, if you uncomment line 5 ("unsigned multiplyerType"), this thing will balloon from 1-byte to 12!

I can explain that if you haven't already.

You changed the basic type of the bit field when you uncommented line 5. It went from trying to put bits into a 1 byte field to trying to put bits into a 4 byte field so it started again at the beginning of a new field. Since the new field is 4 bytes long (an unsigned) it needs to be on a 4 byte boundary so 6 padding bits are put into the original field followed by 3 padding bytes. The first 2 bit field is taking 4 bytes of space!

Then you change back to a 1 byte field so the compiler starts again, again. It puts in 31 padding bits into the 4 byte field and starts a 1 byte field for the final three bit fields.

The it adds 5 padding bits to complete the field. At this point 9 bytes have been used (1 byte field, 3 padding bytes, 4 byte field and 1 byte field), however this is a structure and needs to conform to normal structure padding rules. The structure contains a 4 byte field so needs to align on a 4 byte boundary. To ensure that this happens in a array the compile adds 3 more padding bytes for a total of 12 bytes.

And the moral of this …

Fbody commented: This looks like a better wording of what I had theorized. Thanks. +1
Banfa 597 Posting Pro Featured Poster

In that way you will never be wrong

You will if you have accidentally forgotten to include stdlib.h on a 64bit system. You will be so wrong you will almost certainly crash.

Banfa 597 Posting Pro Featured Poster

If you put in flagGroup to try and set the size of the bitfield then forget it. You need to use the correct type in the bit flied itself.

Banfa 597 Posting Pro Featured Poster

I get this error from your code using gcc

BitFlags.h:12: error: ISO C++ prohibits anonymous structs

What compiler are you using, this is improtant of course because bitfield behaviour is very much platform dependent.

Anyway after naming the struct I get a size of 4 for the struct as you have it defined.

if you want the bitfield size to be 16 bits you need to declare it unsigned short or if you want to use negative values short .

I ended up with this

union bitFlags {
	unsigned short flagGroup; //provide a 16-bit backbone (on 32-bit systems)
	struct { //the bit field
		signed short multiplierRule : 2; //multiples-of-a-kind rule,
		//"on" causes values to be 2x,3x,4x three-of-a-kind value resp.
		unsigned short straightRule : 1; //"on" activates bonus for a straight in a single roll
		unsigned short threePairRule : 1; //"on" activates bonus for three pairs in a single roll
		unsigned short hardWinRule : 1; //"on" activates the hard win rule-set
	} s; //close the bit field structure
}; //close the union

P.S. I would have thought you should know that "it wont compile" is a bit useless without the actual compiler errors :p

Banfa 597 Posting Pro Featured Poster

Actually no you haven't "its not working" is not a proper description of its actual behaviour. All that tells me is that it doesn't do what you want it to do. That doesn't tell me what it actually does.

Banfa 597 Posting Pro Featured Poster

Is this nearly bulletproof?

I think so probably.

I have to admit that I have a, possibly irrational, prejudice against atoi. I do not like the way you can tell how many characters it has parsed without parsing them yourself, as you code does. Every digit gets parsed once by atoi and once by your own loop to verify that it is a digit. That inefficiency, although minute, just sticks in my craw and makes me want to do something different. I do use atoi but normally only in simple little tools that are not destined for consumer contact.

I may be a bit prejudiced against atoi but wild horses could not force me to use strtok. It contains static buffers (well pointers I suspect) so is not re-entrant or thread-safe.

If I was writing this routine then I would either cut out the call to atoi and the while loop and put in a call to strtol or I would cut out the call to atoi and and expand the while loop to do the calculation of the value as well.

while (*p != '\n' && *p != 0 && i < 3 )
    {
        if (isdigit(*p))
        {
            char *end;
            date[i++] = strtol(p, &end, 10);
            if (isSeparator(*end)) p = end + 1;
              else              break;  // non-date character
        }
        else  break;                    // non-date character
    }
while (*p != '\n' && *p != 0 && i < 3 )
    {
        if (isdigit(*p))
        {
            date[i] = 0; …
Banfa 597 Posting Pro Featured Poster

Cowandchicken??

If you mean was that string tailored to the code after I had examined it then yes.

However there is a serious but generalised point here, if the validation does not validate the exact format, with allowable variations, then you let in the possibility that the user manages to type in something that was actually meant to go in a different field but somehow manages to conform loose verification of the field they have typed into the program has unwittingly let in incorrect input.

If the software is in everyday use then the chances of this happening go up and if for some strange reason the cancel input function of the software doesn't work and the software acts on the input even if cancelled they it could be a disaster (don't laugh I've seen it happen).

Not checking that there are no invalid characters between the end of the parsed input and the next separator is sloppy.

Banfa 597 Posting Pro Featured Poster

Not entirely bullet proof since it will interpret my half a shopping list as a date

Enter Date String : 1)Fish.2)Chips.3
   month : 01
   date  : 02
   year  : 2003

Verifying input involves verifying no additional garbage was input too.

Banfa 597 Posting Pro Featured Poster

The rest is left as an exercise for the reader.

lol, thanks but no thanks, my own approach is as far as possible to only work on code that has no direct connections with any people. Their nice and all that but they do tend to muddy the waters :D