Consider this code:
#include <iostream>
int main()
{
int iTemp = 0;
iTemp += 1; // Valid
iTemp + = 1; // This gives an error ( note the space between '+' and '=')
return 0;
}
Should the parser not automatically have consumed this space and checked for the presence of '=' as '+=' is also a valid token, rather than throwing an error ?
Similarly I get an error for doing < iostream >
Can someone please explain.
No, the parser should not have. The specification of the language calls for this behavior, and that's the end of the story.
Doesn't work.
The first step of C compilation is tokenization - breaking the sequence of characters to separate language elements. For example:
int x=333; becomes the list int, x, =, 333 and ;'.
Once this is done, the compiler can figure out which token means what and how to combine them.
If tokenization sees the sequence +=, it generates one token. If it sees a space, it generates two: + and =.
No it should not. The parser is very good but doesn't read minds. It cannot know if either the plus or equals is an error or if the spacing is an error. In any case, the whole thing is an error.
No. += is a single token. + and = are also single tokens respectively.
The specifications specifies a += operator and not a + = one. So the answer is no. while keyword can't be replaced by whi le, it's the same for +=
I remember, back in the dark ages, when the op= tokens had alternative variants =op. So x =+ 5 meant the same as x += 5. This was disastrous, of course, because x=-5 meant x -= 5 instead of x = -5. But even at that early date, these compound tokens were not allowed to contain white space.
+,= and += are different operators. So if you give whitespace between + and =, scanner would tokenise these operators as different operators. And as a result, Syntax Analyzer(Parser) will give a syntax error.
Why would it work?
If you try to increment a = a+ + it won't work either.
Related
I am currently learning C++ from 'Problem solving with C++' (9th, W. Savitch). The book shows an example of a while loop. The while loop looks as follows.
while (ans = = 'Y' || ans = = 'y')
{
//compound statement
}
ans is of type char.
The boolean expression appears to be trying to use the equality operator, and in the context of the //compound statement this makes sense. However, I always thought whitespace was illegal within the equality operator. i.e == is legal, but = = is illegal.
When I copy the code and compile it, my compiler throws the error 'expected expression' when it hits = = as if I am trying to assign an expression to a variable. I am almost certain this is a typo within the book. However, just in case the book is trying to throw a curveball I thought I would ask...
Many thanks!
Is whitespace between the two ='s in an equality operator legal in C++?
No. = = is two = tokens. == is one == token. You can't use the former when you mean the latter.
Suppose you want to convert an integer into string this is the method in c++
int c1=999;
stringstream ss;
ss<<c1;
string str=ss.str();
How is it converting into string in c++? What does the stringstream contains and in the 3rd line of the above program
in that statement i.e I mean what does the left shift operator (as we know that the symbol '<<' is used for left shifting) is doing here to converting into string
To convert an int to string (very basically), you have to go through all digits, translate it to a regular char, and put it in the string :
int toConvert = 999;
string res = "";
while (toConvert)
{
int lastDigit = toConvert % 10; //retrieve last digit
char c = lastDigit + '0'; //translate it to the char corresponding
string reverse(c); //We have to add it in front of the string, or otherwise
reverse.append (res); // the digits will be reversed.
res = reverse;
toConvert /= 10;
}
This is a very basic way to translate int to string, and I'm sure it's done way better in the operator "<<", but you get the idea.
The left shift here is overload by append function, think of it as
ss.append(c1) where the append can have multiple functions
append(int i)
append(string s)
append(byte b)
etc
each function do the actual translation to the right string and appending it...
There's no left shift operator in your code. In C, << was left shift. In C++, it's the stream insertion operator (with support for left shift as well, for reasons of C compatibility).
You are allowed to overload various operators in C++, including bitwise left shift <<. Conceptually you can override it do to anything; the only restriction being that the number of operands can't be changed.
The streaming classes in the C++ IO stream libraries exploit this. It's syntatically cute to use << to write the argument to the stream in some way, as clearly, bitwise shifting a stream has no meaning so the operator may as well be used to do something else. That is what ss<<c1; is doing. It's not doing anything like a bitwise shift.
There is a school of thought that says that operator overloading is confusing (perhaps this is why this question has been asked). That's why operator overloading didn't make it into Java.
<< in this situation isn't exactly the Left Shift Operator.
Its a Stream Operator.
It appends (inserts) the characters in to your string stream.
This question already has answers here:
How does the Comma Operator work
(9 answers)
Closed 9 months ago.
I came across unexpected (to me at least) C++ behavior today, shown by the following snippit:
#include <iostream>
int main()
{
std::cout << ("1", "2") << std::endl;
return 0;
}
Output:
2
This works with any number of strings between the parentheses. Tested on the visual studio 2010 compiler as well as on codepad.
I'm wondering why this compiles in the first place, what is the use of this 'feature'?
Ahh, this is the comma operator. When you use a comma and two (or more) expressions, what happens is that all expressions are executed, and the result as a whole is the result of the last expression. That is why you get "2" as a result of this. See here for a bigger explanation.
It's called the comma operator: in an expression x, y, the compiler
first evaluates x (including all side effects), then y; the results
of the expression are the results of y.
In the expression you cite, it has absolutely no use; the first string
is simply ignored. If the first expression has side effects, however,
it could be useful. (Mostly for obfuscation, in my opinion, and it's
best avoided.)
Note too that this only works when the comma is an operator. If it can
be anything else (e.g. punctuation separating the arguments of a
function), it is. So:
f( 1, 2 ); // Call f with two arguments, 1 and 2
f( (1, 2) ); // Call f with one argument, 2
(See. I told you it was good for obfuscation.)
Comma operator ( , )
The comma operator (,) is used to separate two or more expressions that are included where only one expression is expected. When the set of expressions has to be evaluated for a value, only the rightmost expression is considered.
For example, the following code:
a = (b=3, b+2);
Ref:http://www.cplusplus.com/doc/tutorial/operators/
The result of the comma (",") is the right subexpression.
I use it in loops over stl containers:
for( list<int>::iterator = mylist.begin(), it_end = mylist.end(); it != it_end; ++it )
...
The comma operator evaluates the expressions on both sides of the comma, but returns the result of the second.
Roughly speaking in C++ there are:
operators (+, -, *, [], new, ...)
identifiers (names of classes, variables, functions,...)
const literals (10, 2.5, "100", ...)
some keywords (int, class, typename, mutable, ...)
brackets ({, }, <, >)
preprocessor (#, ## ...).
But what is the semicolon?
The semicolon is a punctuator, see 2.13 §1
The lexical representation of C++ programs includes a number of preprocessing tokens which are used in
the syntax of the preprocessor or are converted into tokens for operators and punctuators
It is part of the syntax and therein element of several statements. In EBNF:
<do-statement>
::= 'do' <statement> 'while' '(' <expression> ')' ';'
<goto-statement>
::= 'goto' <label> ';'
<for-statement>
::= 'for' '(' <for-initialization> ';' <for-control> ';' <for-iteration> ')' <statement>
<expression-statement>
::= <expression> ';'
<return-statement>
::= 'return' <expression> ';'
This list is not complete. Please see my comment.
The semicolon is a terminal, a token that terminates something. What exactly it terminates depends on the context.
Semicolon denotes sequential composition. It is also used to delineate declarations.
Semicolon is a statement terminator.
The semicolon isn't given a specific name in the C++ standard. It's simply a character that's used in certain grammar productions (and it just happens to be at the end of them quite often, so it 'terminates' those grammatical constructs). For example, a semicolon character is at the end of the following parts of the C++ grammar (not necessarily a complete list):
an expression-statement
a do/while iteration-statement
the various jump-statements
the simple-declaration
Note that in an expression-statement, the expression is optional. That's why a 'run' of semicolons, ;;;;, is valid in many (but not all) places where a single one is.
';'s are often used to delimit one bit of C++ source code, indicating it's intentionally separate from the following code. To see how it's useful, let's imagine we didn't use it:
For example:
#include <iostream>
int f() { std::cout << "f()\n"; }
int g() { std::cout << "g()\n"; }
int main(int argc)
{
std::cout << "message"
"\0\1\0\1\1"[argc] ? f() : g(); // final ';' needed to make this compile
// but imagine it's not there in this new
// semicolon-less C++ variant....
}
This (horrible) bit of code, called with no arguments such that argc is 1, prints:
ef()\n
Why not "messagef()\n"? That's what might be expected given first std::cout << "message", then "\0\1\0\1\1"[1] being '\1' - true in a boolean sense - suggests a call to f() printing f()\n?
Because... (drumroll please)... in C++ adjacent string literals are concatenated, so the program's parsed like this:
std::cout << "message\0\1\0\1\1"[argc] ? f() : g();
What this does is:
find the [argc/1] (second) character in "message\0\1\0\1\1", which is the first 'e'
send that 'e' to std::cout (printing it)
the ternary operator '?' triggers casting of std::cout to bool which produces true (because the printing presumably worked), so f() is called...!
Given this string literal concatenation is incredibly useful for specifying long strings
(and even shorter multi-line strings in a readable format), we certainly wouldn't want to assume that such strings shouldn't be concatenated. Consequently, if the semicolon's gone then the compiler must assume the concatenation is intended, even though visually the layout of the code above implies otherwise.
That's a convoluted example of how C++ code with and with-out ';'s changes meaning. I'm sure if I or other readers think on it for a few minutes we could come up with other - and simpler - examples.
Anyway, the ';' is necessary to inform the compiler that statement termination/separation is intended.
The semicolon lets the compiler know that it's reached the end of a command AFAIK.
The semicolon (;) is a command in C++. It tells the compiler that you're at the end of a command.
If I recall correctly, Kernighan and Ritchie called it punctuation.
Technically, it's just a token (or terminal, in compiler-speak), which
can occur in specific places in the grammar, with a specific semantics
in the language. The distinction between operators and other punctuation
is somewhat artificial, but useful in the context of C or C++, since
some tokens (,, = and :) can be either operators or punctuation,
depending on context, e.g.:
f( a, b ); // comma is punctuation
f( (a, b) ); // comma is operator
a = b; // = is assignment operator
int a = b; // = is punctuation
x = c ? a : b; // colon is operator
label: // colon is punctuation
In the case of the first two, the distinction is important, since a user
defined overload will only affect the operator, not punctuation.
It represents the end of a C++ statement.
For example,
int i=0;
i++;
In the above code there are two statements. The first is for declaring the variable and the second one is for incrementing the value of variable by one.
I'm trying to put the coefficients of polynomials from a char array into an int array
I have this:
char string[] = "-4x^0 + x^1 + 4x^3 - 3x^4";
and can tokenize it by the space into
-4x^0
x^1
4x^3
3x^4
So I am trying to get: -4, 1, 4, 3 into an int array
int *coefficient;
coefficient = new int[counter];
p = strtok(copy, " +");
int a;
while (p)
{
int z = 0;
while (p[z] != 'x')
z++;
char temp[z];
strncpy(temp[z], p, z);
coefficient[a] = atoi(temp);
p = strtok(NULL, " +");
a++;
}
However, Im getting an error that I cant convert a char* into a char
on strncpy(temp[z], p, z);
error: invalid conversion from ‘char’ to ‘char*’
error: initializing argument 1 of ‘char* strncpy(char*, const char*, size_t)’
What would be the best way to do this?
This:
strncpy(temp[z], p, z);
Needs to be:
strncpy(temp, p, z);
But remember that strncpy doesn't always null-terminate the string.
Also, z will be the length of the coefficient, but you need an extra byte in the buffer for the null terminator.
Update:
examining your link, I still see several serious problems:
You can't use "-" in strtok because it will pick up the one in "-4x" as well as the ones you want. I think you should split on spaces only and handle the +/- operators as tokens.
The strncpy function leaves the string un-terminated, which may cause atoi to crash or give the wrong value randomly. One idiomatic form is to write the terminator manually, e.g., temp[z] = '\0'.
The reason you're not getting any output values is that coefficient[a] = is writing to some random memory because a is uninitialized.
You're passing a char to strncpy:
strncpy(temp[z], p, z);
The first argument should be a char* pointer, not a single char. What you probably mean to do is:
strncpy(temp, p, z);
The other guys are correct about strncpy()'ing into temp rather than temp[z].
I'm going to suggest that you also want to capture the exponents on your free variable. I observe an implicit "0x^2" term that you appear to be neglecting. If your next step is to evaluate your polynomial for various values of x (or, worse, run a solver on it), you will need to know those powers.
This kind of a solution can be made easily enough but to make it proof against extra white space, missing white space and broad enough to handle multiple operators and variable names this kind of strategy increasingly complex and difficult (Especially if you need to have meaningful error messages if the parse fails).
Seems to me it would be easier to implement a bullet-proof solution using boost.regex (or even boost.spirit if the overall task requires order of operations to be analysed) which can easily handle these kind of syntaxes with a large degree of tolerance.