grumpier 149 Posting Whiz in Training

break statements can be used in looping constructs, and in switch/case blocks. They cannot be used to break out of an "if" block, or as an alternative means of returning from a function.

Also, <iostream.h> is non-standard. #include <iostream> instead.

grumpier 149 Posting Whiz in Training

I'll wager a bet that he means "The most efficient" means by which to add a value to all items in an array.

I'd be betting on your side. But that just means he then needs to define the criterion for "The most efficient". For example, does it mean "fastest", "smallest number of machine instructions", "least memory consumption", "least heat output from the CPU" :)

He probably also needs to specify the type of array elements. Adding a value to elements of an array of strings might conceivably require a technique that differs from adding a value to elements of an array of int.

Incidentally, I despise irrelevant questions that put carts before horses. ;)

grumpier 149 Posting Whiz in Training

You're developing a realtime application, and don't know how to add values to elements of an array?????

Pull my other leg: it'll play a tune for you.

What is the criterion by which you would describe a method as "best"? If you are truly designing a realtime application, you will realise the significance of that question.

Salem commented: Jingle bells, jingle bells, jingle all the way? +26
grumpier 149 Posting Whiz in Training

An explicit conversion is what you're calling a cast. An implicit conversion is a conversion between types that the compiler allows or performs, even if you don't do a cast. For example;

int i = 3;
   long j = i;

The initialisation of j involves an implicit conversion of an int to a long. The compiler knows how to do that, so it happens implicitly (as far as the programmer is concerned).

Conversion between basic types are built in: for example, the compiler knows how to add an int to a double.

Class types support conversions in two ways: by the constructors they supply, and by operator functions.

class X
{
    public:
       X(const char *);
};

allows a const char pointer to be converted to an X. Given a function;

void func(const X &);

the call

func("Hello");

will create a temporary X by passing "Hello" to its constructor, and then pass that temporary to func(). That process of creating the temporary X from "Hello" is a conversion.

The other way is that;

class Y
{
     public:

         operator const char *() const;  // conversion to const char *
};

declares an operator that allows a Y to be converted to a const char *. So, given;

void another_func(const char *);

it is possible to do this;

Y y;   / assume we have a default constructor
    another_func(y);

as the compiler will implicitly invoke the operator const char *() for the object y, …

grumpier 149 Posting Whiz in Training

Should I avoid casting between data types?

As a general rule, yes you should.

I haven't really seen much about the use of this, but it seems like one of those last-minute-no-way-around kind of methods... but, for example, how would I use the length of a string in a for loop? The length property of a string is size_t, and if I had an integer i in a loop, how could I do that?

An implicit conversion exists between int and size_t so, in rough terms, you shouldn't need an explicit conversion between them.

Note "explicit conversion" is actually the more correct name for a "cast".

In practice, the conversion can lose information (signed to unsigned, and different variable sizes), so several compilers will emit a warning when doing that conversion. If (and I repeat if) you know that conversion is valid, you can safely ignore the warning messages. If you can't tolerate warning messages from compilers, then an explicit conversion generally has the side effect of stopping the compiler complaining. That has the disadvantage that it also stops the compiler from emitting complaints that you should really address properly.

However, if you can guarantee the conversion is safe (i.e. you know that the value of the size_t variable can be stored in an int) a technique is;

size_t end = whatever();
   for (int i = 0; i < (int)end; ++i)
      loop_body();

Where would casting be useful?

Explicit conversions are useful when you know a conversion …

grumpier 149 Posting Whiz in Training

Try this. Comments added explaining the reason for change from your code.

#include <iostream>      // <iostream> is standard, <iostream.h> is not
#include <cstring>        //   need functions to work with C strings

using namespace std;
class Dummy{
char Name[256];

public:    // for main() to use a member function, it must be public
void setName(char *nam)       // arrays are passed to function as pointers
    {strcpy(Name, nam);}   // and char arrays are copied using string functions like strcpy()
};

int main(){
char temp[256];           //   the declaration char [256] temp is invalid
cout << "Name?\n";
cin >>  temp;
Dummy some_object;   //  non-static member functions act on objects
some_object.setName(temp);  // this is how non-static member functions act on objects
}

You also need to put some effort into interpreting and understanding error messages from your compiler. Your compiler would have complained bitterly about your code and, if you'd taken time to understand them, you could worked out the changes I've commented in red.

grumpier 149 Posting Whiz in Training

If the content of header A relies on content of header B, then it is generally a good idea for header A to #include header B. Examples of "relies on" are;

- header B declares a base class, and a class in header A inherits from it.
- header B defines a type (eg classes, enums, typedefs) and any function in header A accepts arguments or returns that type.

grumpier 149 Posting Whiz in Training

You need to understand the difference between registering a callback function and actually calling it.

Setting TButton's OnClick event egisters a function that will be called when the user - eventually - presses the button. It does not call the function directly.

If, when the user presses the button, you want a particular function called, then call your function within the callback function (eg in the body of OnClick1). If you register the callback (eg TestBtn->OnClick = OnClick1;), then OnClick1 callback will be called whenever a user presses TestBtn. If OnClick1 calls myfunction(parameter) ......

grumpier 149 Posting Whiz in Training

TButton's constructor needs to be passed a pointer to a TComponent (eg a parent form) that is responsible for managing the button.

It is also necessary to set various attributes: position, caption, visibility, the function to be called when the newly created button is created, etc etc. TButton is derived from TWinControl, so some inherited attributes probably also need to be set.

It would probably be easier to create a button on your form at design time, and have your function make that button visible as needed.

grumpier 149 Posting Whiz in Training

The only way in which a constructor can report an error is by throwing an exception.

The C++ standard has this to say (in Section 15.2 "Constructors and destructors" which is within Section 15 "Exception Handling"). [Note: I have not preserved font changes or emphasis in the quote]

1 As control passes from a throw-expression to a handler, destructors are invoked for all automatic objects constructed since the try block was entered. The automatic objects are destroyed in the reverse order of the completion of their construction.

2 An object that is partially constructed or partially destroyed will have destructors executed for all of its fully constructed subobjects, that is, for subobjects for which the constructor has completed execution and the destructor has not yet begun execution. Should a constructor for an element of an automatic array throw an exception, only the constructed elements of that array will be destroyed. If the object or array was allocated in a new-expression and the new-expression does not contain a new-placement, the deallocation function (3.7.3.2, 12.5) is called to free the storage occupied by the object; the deallocation function is chosen as specified in 5.3.4. If the object or array was allocated in a new- expression and the new-expression contains a new-placement, the storage occupied by the object is deallocated only if an appropriate placement operator delete is found, as specified in 5.3.4.

3 The process of calling destructors for automatic objects constructed on the path from a try …

rkumaram commented: good +1
grumpier 149 Posting Whiz in Training

When you mark a method of your class as virtual you give the user of your class the possibility to override that method. If you don't, the metod can't be overridden.

That statement is inaccurate on so many levels that I'm speechless. Non-virtual functions can also be overridden, but the behaviour differs from overridden virtual functions due to "name hiding", as described in the C++ standard.

The point of virtual member functions is that they allow functionality to be specified in a base class, and specialised in a derived class. For example, a generic Shape class might declare a virtual function named Area() to compute it's area, and another virtual function called Name(). Derived classes (which represent particular shapes) override those virtual function to give appropriate results for particular shapes.

class Shape
{
     public:
          Shape();
          virtual double Area() const = 0;
          virtual std::string Name() const = 0;
};

class Triangle: public Shape
{
     public:
          Triangle(double h, double w) : height(h), width(w) {};
          double Area() const {return 0.5*height*width;};

          std::string Name() const {return "Triangle";}

     private:
          double height, width;
};

class Circle : public Shape
{
     public:
         Circle(double r): radius(r) {};
         virtual double Area() const {return 4.0*atan(1.0)*radius*radius;};
          virtual std::string Name() const {return "Circle";}
      private:
            double radius;
};

Now, let's say we have a function that only knows about the Shape class, and wishes to print its name and area. For example;

void PrintArea(const Shape &s)
{
    std::cout << s.Name() << " - Area = " << s.Area() << '\n';
}
ddanbe commented: you made a point +3
Manutebecker commented: Excellent Post +1
grumpier 149 Posting Whiz in Training

ah I see - dang that should be an error or a warning or something, shouldn't it??

In an ideal world, where compiler vendors care about perfectly diagnosing all errors in code, yes. In the real world, where compiler vendors prefer to focus attention on other things (eg performance) no.

In the real world it is undefined behaviour: it is actually a runtime error (tromping over memory) but compilers can't always predict runtime behaviour.

Your example;

char pos[5];
sprintf(pos, "%05d", 1);

can easily be converted into;

char pos[5];
some_function(pos);

//   and in some other source file

void some_function(char *x)
{
    sprintf(x, "%05d", 1);
}

so, at the point of the sprintf() call, the compiler has no information about the allocated length of string passed to some_function(). It is often technically VERY difficult for compilers to detect such cases.

Because of these possibilities (a compiler might be able to detect your case, but not technically able to detect the same problem after a minor code restructuring), the C++ standard simply defines both cases to be "undefined". This allows compiler vendors to simply ignore the thornier problems.
Compiler vendors therefore tend not to bother with detecting such things, particularly when programmers insist on the compilers giving features (fast compilation, good runtime performance) while remaining inexpensive.

grumpier 149 Posting Whiz in Training

It is necessary for the derived class to override all inherited pure virtual functions, otherwise the derived class remains an abstract class.

grumpier 149 Posting Whiz in Training

Provide a small but complete example of code that exhibits your problem.

Your code sample and description is not complete, and the cause of the error is probably in something you haven't shown or described.

grumpier 149 Posting Whiz in Training

Your problem is actually the first four lines of the main() function. I've added comments to the code that are related to problems on each line.

void main()    // main should return int, not void
{
sLink* pChainLink; // uninitialised pointer
sLink ChainLinkNo1 (pChainLink, 1);   // undefined behaviour: accessing value of uninitialised pointer
sLink ChainLinkNo2 (ChainLinkNo1, 2);    // compiler error: ChainLinkNo1 not a pointer, sLink's constructor expects one
sLink ChainLinkNo3 (ChainLinkNo2, 3);  // compiler error: ChainLinkNo2 not a pointer, sLink's constructor expects one

The only reason the compiler is complaining about the line you have highlighted is that it is the only constructor that might be invoked by your code, but you've provided the wrong type of argument.

grumpier 149 Posting Whiz in Training

The C++ standard explicitly allows compilers to eliminate temporary objects if the only way of detecting if those temporary objects exist is to track constructor and destructor calls.

A special case of this is the Return Value Optimisation (RVO), which your compiler is implementing. This optimisation basically means the compiler can avoid multiple copies if a variable within your function (eg temp within operator+()) will only be copied into a variable in the caller (eg S3 in main()).

grumpier 149 Posting Whiz in Training

Your main.cpp needs to have visibility of the definition of the conversion (or cast) operator. In other words, the implementation of the operator needs to be inlined into the vector.h: otherwise the compiler cannot instantiate the template.

Unrelated to your problem: it is usually a good idea for copy constructors to have their arguments const: copying an object usually does not change the original.

grumpier 149 Posting Whiz in Training

You are making the mistake of assuming that integer division yields a floating point result - it doesn't: it yields an integer result and integers can't represent fractions.

In your code i/2231 is an integer division, and yields an integer result by rounding towards zero (hence always yields zero if i is in the range [0,2231) ).

You need to force the division i/2231 to be a floating point division to get the result you expect. For example;

ShowProgress = ((double)i / 2231) * 100;

or

ShowProgress = (i / 2231.0) * 100;
grumpier 149 Posting Whiz in Training

If there are common things that all classes which handle triangles have to do, put those functions into their own class (eg TriangleModelFile derived from ModelFile). Derive the specific/multiple classes (eg SpecificTriangleModelFile) from that generic triangle-handling class, and give it specific behaviour it requires.

It's often a good idea to make base classes are abstract (i.e. you can't instantiate them) and derived classes are concrete (i.e. they can be instantiated). That way you reduce the temptation to move things to a base class that are only needed by some derived classes.

Alex Edwards commented: Great advice =) +4
grumpier 149 Posting Whiz in Training

Don't use the first option. The whole point of a Base class is capturing functionality that is common to all derived classes.

As to the second option, there are many ways. Such as....

Provide a protected virtual function named UpdatePoints() in your base class. Implement it to do nothing (i.e. a body with nothing in it). Call it from your MovePoints() function, preferably after updating the vector<Point> member.

Override it in the derived class as appropriate (eg in your class with triangles, use it to update the vector<Triangle> based on the updated points).

Making it protected simply ensures it can't be called outside the class hierarchy (as there's probably no point in that). That's optional, depending on whether you want to allow it to be called by arbitrary code, obviously.

grumpier 149 Posting Whiz in Training
void main()

Wash your mouth out with soap. main() returns int.

grumpier 149 Posting Whiz in Training

im trying for over 3 hours to understand and inbed what you suggesting, but get errors during compilation, i'm very new to c, and dont fully understand the terminology yet, do you mean to put && printf("Invalid Entry"); and nest it during condition of while statement?

i feel embaressed, sorry for such goofy questions

I'll answer your question with a question.

Under what conditions will

if ((x < 1 || x > 4) && printf("Goofy"))
{
    printf(" is also known as Dippy Dawg");
}

print out "Goofy is also known as Dippy Dawg"?

grumpier 149 Posting Whiz in Training

A post-test loop is a generic name for a loop of the form do { ... } while (condition), as opposed to a while(condition) {} loop.

The solution, if you have to do that, is to have the printf() statement reporting the error within the loop condition. To do that use;

1) shortcutting occurs with operations like && and ||. For example, if x is true, a test x && y does not evaluate y.

2) printf() returns the number of bytes output i.e. if it succeeds in printing your error message, it will return a non-zero (i.e. true) value.

grumpier 149 Posting Whiz in Training

(1) strtok() assumes both its arguments are strings that are terminated with a 0 character. Behaviour is undefined if that is not true.

2) strtok also returns NULL if it cannot find a token being searched for. strcmp() yields undefined behaviour if either argument is NULL.

3) A segmentation fault is one possible symptom of undefined behaviour.

4) The fact that you are observing a segmentation fault is occurring at a "precise point" is irrelevant. The cause of segmentation faults is not necessarily the line where they are reported: the actual cause can be any code executed at or before that point.

grumpier 149 Posting Whiz in Training

Not even close.

Your code does not insert any characters into the string array. What is the purpose of the "input" argument supplied to the function? where is the codes counting the number of characters read (or inserted into a string)? Where is code to make it terminate at whitespace? The length of the input string size may be arbitrary, but how does your code stop writing past the end of that length?

grumpier 149 Posting Whiz in Training

The only reason this code should give you error is if you input something else that float, let's say letter [...]

scanf() would return an EOF in that case.

No it will not. It will return zero in that case.

EOF is only returned upon reaching end of input. If there is input in the stream that does not correspond to what is expected (via the format string) scanf() returns the number of fields successfully read. If there is one value to be read, and none are, the return value is zero.

Not that it matters: the return value of scanf() is not being checked.

In any event, the code that is posted is probably different from the code being compiled. And the difference is where the error is.

grumpier 149 Posting Whiz in Training

Your function highestTest() does not initialise the variable "highest", but the first operation involves comparing its value with elements of the array. That means the value it ends up with in that function will probably be junk.

The printHighest() function declares its own local variable named highest (again uninitialised so it contains junk) and prints it out.

The variable highest within printHighest() also has no relationship to the variable named highest in highestTest(): although they happen to have the same name, they are both local to the particular functions.

If you have any questions .... think first before you ask. You might be able to answer them yourself, and you will be better off if you can.

grumpier 149 Posting Whiz in Training

Yes. Look up the C standard header stdarg.h or (in C++) the standard header <cstdarg>. Those headers contain macros and types that support writing functions with variable argument lists.

grumpier 149 Posting Whiz in Training

Apart from that, it often takes a lot more effort to write assembly code to achieve X than it does to do X in a higher level language like C. C also has a library .... which means it is not necessary to code everything from scratch.

As an exercise, try getting to the stage where you have some level of familiarity with both assembler (on your target machine) and with C. Then pick a reasonably non-trivial programming task that seeks to read data from files, do some processing, and write data back to files. First implement it in assembler, and track how long it takes. Take a week off to clear your head. Then implement it in C, (without looking at any of the design or code from your assembler work) and track how long that takes.

When you've done that, report back here (I'll look forward to seeing your post in a couple of months).

Odds are, you will find things take you a lot longer with assembler.

grumpier 149 Posting Whiz in Training

When you append pointers onto a vector of char, the pointer is copied. You are expecting the data the pointer points at to be copied.

With a vector<char *> you need to explicitly copy the data as well as the pointer.

An easier way would be to use a std::vector<std::string> instead (as std::string objects copy the data implicitly).

grumpier 149 Posting Whiz in Training

There is also the incidental concern that your function is recursive, which does not meet the requirement to be non-recursive.

grumpier 149 Posting Whiz in Training

A c-style string (eg a string literal) is an array of char that, by convention, is terminated with '\0'.

grumpier 149 Posting Whiz in Training

So, my query is, why this is happening only in case of strings and not for the others( like int, float, single character)?

Because the %s format specifier tells printf() and related function that the corresponding argument is a pointer to char and to keep printing chars until it finds a zero.

When an array is passed to a function (be it array of char, double, or structs) only a pointer to the first element is passed. No information about the number of elements in the array is passed. So the function has to use some convention (as printf() does with the %s specifier) or make an assumption (eg it assumes the array is of length 5).

grumpier 149 Posting Whiz in Training

Hi,
But, when we define any character array as
char a[3]={'a','b'};
then compiler here automatically consider '\0' null character to represent the end of the string

That's not true. You have explicitly initialised two elements of three-element array. The standards go about it in a round-about way (there's a logic train to follow to get to the conclusion, and the C and C++ standards have different logic trains) but the end result is that a[2] in your example will get a value of zero.

You will get the same effect (other than type of elements) with

int a[3] = {1, 2};

ie a[2] will get the value of zero.


So, my question here is:
As compiler do not needs to use any such terminator to indicate that the int array or float array is terminated. Then, why compiler needs to assign '\0' null terminator in char array & why not in others?

It doesn't. If the number of explicitly initialised elements of an array is less that the size of the array, the standards specify how the other elements are initialised.

There is an anomaly in C (and C++) that allows char arrays to be initialised using strings (and arrays of wchar_t to be initialised with wide strings). Strings, by convention, are zero terminated. There is no equivalent to this style of initialisation for other types. But this anomaly is a different thing from what you're asking about.

grumpier 149 Posting Whiz in Training

Maybe you can use your formula in an actual code example?

Well, I could. But that takes the challenge of problem solving away from you.

Look back in my previous posts in this thread for definition of T, n, etc.

VernonDozier has worked out what I'm saying which is evidence that, with a bit of effort, you will be able to as well.

grumpier 149 Posting Whiz in Training

Start with T(0) = 1.

In a loop use the fact that T(n+1) = x*T(n)/(n+1) to compute each term. Add the terms together.

ohnomis commented: HE IS THE SOLVER OF e^x! GENIUS! +1
grumpier 149 Posting Whiz in Training

I have no idea how your teacher's program works -- you would have to post it. I can only suspect he used one of the huge integer libraries like I previously suggested. Its also possible he used strings instead of integers to avoid the limitations of integers.

Oh, please! Huge integer libraries or strings are needed for some things, but falling back on them for basic problems like this is crazy.

The program can go to much higher terms simply using the fact that e^x = 1 + x/1! + x^2/2! + ... and that the n-th term inthis is T(n) = x^n/n! It is trivial to show that T(n+1) = x*T(n)/(n+1).

The code to use this relationship to compute an approximation of e^x is easy. This avoids the possibility of overflow that is inherent in computing x^n or n! separately.

Salem commented: Good answer. +22
grumpier 149 Posting Whiz in Training

Well, I'm not sure if that is the case because I ran tests throughout my developArray function, after each individual thing, and it only changes once it hits the red sections.

No .... you mean your tests did not detect a problem. Your tests will only check things you think to test. If you didn't anticipate the particular problem that is occurring, a fault will get past your testing and cause chaos later.

In practice, at least 95% of problems with "variables changing in unexplained ways" result from some code that the programmer has previously tested and insists is unrelated to the problem. I believe that is happening for you.

It's fine before the red, but changes after if goes through the each createBit() line. The odd this is that BitAB and BitB are changed, but BitA has no issue what so ever.

Yep. That's the way it goes. Symptoms caused by malfunctioning code tend to manifest in odd ways .....

Now, one thing I thought about is should I just get rid of createArray and put all those call functions back into the main() cause perhaps that would eliminate the issues but I don't see why that would change anything.

That's because you are assuming the cause of the problem is the code where you see the problem. Whereas, code that is run previously is also a candidate as the cause.

grumpier 149 Posting Whiz in Training

The cause of your problem is almost certainly code executed before your red lines are reached.

My guess - although you haven't shown them - is that the problems really occur in your input() function or, possibly in your createArray() or removeDup() functions.

I'd even guess further that - in writing those functions - you have assumed that an array size can magically change within those functions. If so, you are mistaken. So one of those functions is falling off the end of one of your arrays and corrupting random memory.

Also note that you are passing ALast - an uninitialised variable - to input(). If input() uses its original value you get undefined behaviour. If input() sets ALast to something more than 10, and then loops over the array (from 0 to ALast-1) it will fall off the end of the array. Similar comments for BLast.

A couple of general tips: when trying to find problems like this

1) Do not assume a problem occurs at the point it is detected. The cause is almost certainly code executed before the problem is detected.

2) Try to find a small but complete sample of code that illustrates your problem. In the process of getting to that small but complete sample you might identify the problem yourself. If not, you are not relying on people to work out what is happening in code you have not provided.

grumpier 149 Posting Whiz in Training

Not even close.

You have declared myclass's length() method as taking one argument, and yourlen() calls it with two arguments.

Similarly, yourlen() is declared with no arguments, but when you call it you pass two to it. (I'll ignore the typo of calling a.youlen() rather than a.yourlen()).

If you declare a function taking n arguments, you have to pass exactly n arguments to it.

If you had tried to compile your code, your compiler would have complained bitterly.

grumpier 149 Posting Whiz in Training

Firstly, your variables a, b, and c are uninitialised: their value before entering the loop could be anything.

As to your loop, it doesn't really make sense.

You only need two variables. An index, that gets a value of 1 first time through the loop, 2 the second time, 3 the third time, etc. And a sum, which initially has a value of zero, and each time through the loop has the value of index added to it.

Try using descriptive variable names, and get rid of the "#define p printf" line. If you want to use printf, then type its name in full. Brevity is all well and good, but you've gone too far and have code which is not that easy for a mere mortal to understand, and therefore difficult to get right. You're lucky the code is small.

Oh: learn how to use code tags, so you code is laid out in a readable manner in your posts.

Nick Evan commented: All excellent tips +9
grumpier 149 Posting Whiz in Training

- avoids dangerous recursive call of main()

In C++, recursive call of main is not allowed at all.

To answer the original question, if you must be able to execute a program that reads from standard input and writes to standard output, you need to investigate input and output redirection (ie. redirecting of stdout to a file, redirecting stdin so input is taken from a file).

grumpier 149 Posting Whiz in Training

Try closing outputfile before attempting to open it as an input file.

grumpier 149 Posting Whiz in Training

Dragon's approach will work .... the only other obstacle is the fact that most systems allow a process to have only a small number of files open simultaneously. If you exceed that number, .....