I have been pondering a multiple choice question on coercion. One of the 4 examples a,b,c or d is an example of coercion. I narrowed it down to A or B. But I am having a problem choosing between the two. Cane someone please explain why one is coercion and one isn't.
A)
string s="tomat";
char c='o';
s=s+c;
I thought A could be correct because we have two different types, character and string, being added. Meaning that c is promoted to string, hence coercion.
B)
double x=1.0;
double y=2.0;
int i=(int)(x+y);
I also thought B was the correct answer because the double (x+y) is being turned into a int to be placed in i. But I thought this could be wrong because its being done actively through use of (int) rather than passively such as "int i = x + y"
I'll list the other two options, even though I believe that neither one is the correct answer
C)
char A=0x20;
A = A << 1 | 0x01;
cout << A << endl;
D)
double x=1.0;
double y=x+1;
return 0;
I'm not just looking for an answer, but an explanation. I have read tons of things on coercion and A and B both look like the right answer. So why is one correct and the other not.
I actually think it's B. Even though there's the explicit (int), it's still type coercion (just not automatic type coercion). You're converting a floating point value (probably stored as an IEEE floating point value) to an integer value (probably stored in two's complement).
Whereas A is simply concatenating a character to a string, where a string is just a null terminated array of characters. There's no data type conversion going on there, just a bit of memory manipulation.
I could be wrong though.
EDIT: I would have to agree with Parris. Given that this is a C++ string and not a C array of characters (my mistake), the chracter in A is probably being coerced to a string.
I don't think type casting is equivalent to type coercion, which is why A would probably be the right answer.
B takes a double and casts it to an int, which is more like a conversion than a coercion. In A you aren't converting anything you're being implicit. You are telling the runtime/compiler/whatever "these 2 things are similar can you figure out how to concatenate them?"
C isn't a conversion or coercion its just bit shifting. Although the cout might be coercion... I am not sure if there is coercion to a string there to write to the console.
D might contain a coercion since 1 is an int and you are adding it to a double. However, you can do floating point math with integers having a decimal is just more explicit.
I think A is the most straight forward example of coercion. Although C's cout statement seems suspicious as well.
Related
While experimenting with the zig syntax, I noticed the type expression of string literals is omitted in all examples. Which is totally fine, I'm not saying it shouldn't be.
const zig_string = "I am a string"; //it looks nice enough for sure and compiles fine ofcourse
However, because this type omission is a bit inconsistent* with other type declarations in zig, it can lead to beginners (like me) misinterpreting the actual type of string literals (which is fact quite rightfully complicated and 'different'). Anyway, after reading about the type of string literals being 'pointers to (utf-8 encoded) immutable (const), sentinel terminated arrays of u8 bytes' (yes?), with next to the hard coded length field, a terminator field like so: [<length>:0]. To check my own understanding, I thought it reasonable to try adding this type expression to the declaration, similar to how other arrays are conveniently declared, so with an underscore to infer the length, because who likes counting characters?
const string: *const [_:0]u8 = "jolly good"; //doesn't compile: unable to infer array size
But it didn't compile :(.
After dutifully counting characters and now specifying the length of my string however, it proudly compiled :)!
const string: *const [10:0]u8 = "jolly good"; //happily compiles
Which led me to my question:
Why is this length specification needed for string literals and not for other literals/arrays? - (And should this be so?)
Please correct my type description of string literals if I missed an important nuance.
I'd like to know to further deepen my understanding of the way strings are handled in zig.
*although there are more cases where the zig compiler can infer the type without it
Types never have _ in them.
"jolly good" is a string literal. *const [10:0]u8 is the type.
For "other literals/arrays":
const a = [_]u8{ 1, 2, 3 };
[_]u8{ 1, 2, 3 } is an array literal. The type is [3]u8 and it cannot be specified as [_]u8.
Look into slices. They offer a very convenient way to use strings and arrays.
well i was reading some common concepts regarding parsing in compiler..i came across look ahead and read ahead symbol i search and read about them but i am stuck like why we need both of them ? would be grateful for any kind suggestion
Lookahead symbol: when node being considered in parse tree is for a terminal, and the
terminal matches lookahead symbol,then we advance in both parse and
input
read aheadsymbol: lexical analyzer may need to read some character
before it can decide on the token to be returned
One of these is about parsing and refers to the next token to be produced by the lexical scanner. The other one, which is less formal, is about lexical analysis and refers to the next character in the input stream. It should be clear which is which.
Note that while most parsers only require a single lookahead token, it is not uncommon for lexical analysis to have to backtrack, which is equivalent to examining several unconsumed input characters.
I hope I got your question right.
Consider C.
It has several punctuators that begin the same way:
+, ++, +=
-, --, -=, ->
<, <=, <<, <<=
...
In order to figure out which one it is when you see the first + or - or <, you need to look ahead one character in the input (and then maybe one more for <<=).
A similar thing can happen at a higher level:
{
ident1 ident2;
ident3;
ident4:;
}
Here ident1, ident3 and ident4 can begin a declaration, an expression or a label. You can't tell which one immediately. You can consult your existing declarations to see if ident1 or ident3 is already known (as a type or variable/function/enumeration), but it's still ambiguous because a colon may follow and if it does, it's a label because it's permitted to use the same identifier for both a label and a type/variable/function/enumeration (those two name spaces do not intersect), e.g.:
{
typedef int ident1;
ident1 ident2; // same as int ident2
int ident3 = 0;
ident3; // unused expression of value 0
ident1:; // unused label
ident2:; // unused label
ident3:; // unused label
}
So, you may very well need to look ahead a character or a token (or "unread" one) to deal with situations like these.
I am doing some simple hex comparison in an if statement.
0x7843E0 is greater than 0x780000 but the code below doesn't output anything.
if {"780000" <= "7843E0"} {
puts "True!"
}
>>
Omitting the trailing 0 works fine however.
if {"780000" <= "7843E"} {
puts "True!"
}
>>> True!
There must be something wrong with the trailing 0 but I don't understand what it is. Any ideas?
You're having problems with the way the expr command parses numbers. (The rest of Tcl is more relaxed about this.) The issue is that:
"780000" gets interpreted as a decimal integer.
"7843E0" gets interpreted as a double precision floating point number. (Compare with 1.2e10; the number parser thinks it is fitting the same sort of pattern.)
"780000" gets interpreted as a decimal integer.
"7843E" gets interpreted as a non-numeric string (a fallback because no numeric interpretation is legal).
The <= operator will happily compare two numbers if they're both numbers, or two strings if at least one of the parameters to it is non-numeric. (Yes, this does make for weird semantics occasionally.) Moreover, he expr command is eager to interpret values as numbers if it possibly can, but it still has Tcl's syntactic rules for what actually is numeric, and what type of numeric those things are. When you don't stick to the rules, it gets a bit odd.
To get a value interpreted as hexadecimal, you have to either prefix its string representation with 0x (e.g., 0x7843E0) or force things with a command such as scan with %x:
scan "780000" %x a
scan "7843E0" %x b
if {$a <= $b} {
puts "True"
}
Forcing interpretations with scan is considered to be one of the best ways of dealing with this, as that only writes canonical values into variables. (If you'd been wanting to handle octal numbers, or were wanting to really always be decimal, you'd use %o and %d respectively; %f is for floating-point numbers.)
Finally, if you're really comparing values as strings with normal ASCII-like rules, look at string compare instead of using <= directly.
if {[string compare $input1 $input2] <= 0} {
...
}
I'm wondering if there is a standard way, if we are pronouncing typographical symbols out loud, for reading the << and >> symbols? This comes up for me when teaching first-time C++ students and discussing/fixing exactly what symbols need to be written in particular places.
The best answer should not be names such as "bitwise shift" or "insertion", because those refer to more specific C++ operators, as opposed to the context-free symbol itself (which is what we want here). In that sense, this question is not the same as questions such as this or this, none of whose answers satisfy this question.
Some comparative examples:
We can read #include <iostream> as "pound include bracket iostream
bracket".
We can read int a, b, c; as "int a comma b comma c
semicolon".
We can read if (a && b) c = 0; as "if open parenthesis a double ampersand b close parenthesis c equals zero semicolon".
So an equivalent question would be: How do we similarly read cout << "Hello";? At the current time in class we are referring to these symbols as "left arrow" and "right arrow", but if there is a more conventional phrasing I would prefer to use that.
Other equivalent ways of stating this question:
How do we typographically read <<?
What is the general name of the symbol <<, whether being used for bit-shifts, insertion, or overloaded for something entirely new?
If a student said, "Professor, I don't remember how to make an insertion operator; please tell me what symbol to type", then what is the best verbal response?
What is the best way to fill in this analogy? "For the multiplication operation we use an asterisk; for the division operation we use a forward-slash; for the insertion operation we use ____."
Saw this question through your comment on Slashdot. I suggest a simpler name for students that uses an already common understanding of the symbol. In the same way that + is called "plus" and - is (often) called "minus," you can call < by the name "less" or "less-than" and > by "greater" or "greater-than." This recalls math operations and symbols that are taught very early for most students and should be easy for them to remember. Plus, you can use the same name when discussing the comparison operators. So, you would read
std::cout << "Hello, world!" << std::endl;
as
S T D colon colon C out less less double-quote Hello comma world exclamation-point double-quote less less S T D colon colon end L semicolon.
Also,
#include <iostream>
as
pound include less I O stream greater
So, the answer to
"Professor, I don't remember how to make an insertion operator; please tell me what symbol to type."
is "Less less."
The more customary name "left/right angle bracket" should be taught at the same time to teach the more common name, but "less/greater" is a good reminder of what the actual symbol is, I think.
Chevron is also a neat name, but a bit obscure in my opinion, not to mention the corporate affiliation.
A proposal: Taking the appearance of the insertion/extraction operators as similar to the Guillemet symbols, we might look to the Unicode description of those symbols. There they are described as "Left-pointing double angle quotation mark" and "Right-pointing double angle quotation mark" (link).
So perhaps we could be calling the symbols "double-left angle" and "double-right angle".
My comment was mistaken (Chrome's PDF Reader has a buggy "Find in File" feature that didn't give me all of the results at first).
Regarding the OP's specific question about the name of the operator, regardless of context - then there is no answer, because the ISO C++ specification does not name the operators outside of a use context (e.g. the + operator is named "addition" but only with number types, it is not named as such when called to perform string concatenation, for example). That is, the ISO C++ standard does not give operator tokens a specific name.
The section on Shift Operators (5.8) only defines and names them for integral/enum types, and the section on Overloaded Operators does not confer upon them a name.
Myself, if I were teaching C++ and explaining the <</>> operators I would say "the double-angle-bracket operator is used to denote bitshifts with integer types, and insertion/extraction with streams and strings". Or if I were being terse I'd overload the word and simply say "the bitshift operator is overloaded for streams to mean something completely different".
Regarding the secondary question (in the comment thread) about the name of the <</>> operators in the context of streams and strings, the the C++14 ISO specification (final working-draft: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4296.pdf ) does refer to them as "extractors and inserters":
21.4.8.9 Inserters and extractors
template<class charT, class traits, class Allocator>
basic_istream<charT,traits>&
operator>>(
basic_istream<charT,traits>& is,
basic_string<charT,traits,Allocator>& str
);
(and the rest of the >> operator overload definitions follow)
This is further expanded upon on 2.7.2.2.2:
27.7.2.2.2 Arithmetic extractors
operator>>(unsigned short& val);
operator>>(unsigned int& val);
operator>>(long& val);
(and so on...)
cout << "string" << endl;// I really just say "send string to see out. Add end line."
i++; // i plus plus
auto x = class.func() // auto x equal class dot func
10 - ( i %4) * x; // ten minus the quantity i mod four times x
stdout // stud-out
stderr // stud-err
argc // arg see
argv // arg vee
char* // char pointer
&f // address of f
Just because it's an "extraction" or an "insertion" operator does not mean that is the OPERATION.
The operation is "input" and "output"
They are stream operators.
The natural label would be c-out stream output double-quote Hello world exclamation double-quote stream output endline
This the OPERATION you are doing (the verb)
What the ARM calls the operator is irrelevant in that it is a systemic way of looking at things and we are trying to help humans understand things instead
In the first step itself of converting an infix to prefix can someone explain in simple terms why should we reverse the string? Is there any alternative method to convert?
Yes, you are absolutely right that if you have to convert infix to prefix then you have to scan the string from right to left.
Why not from left to right?
If you scan from left to right then you will require future knowledge of operators in the string.
Example 1 :
Infix : 2+3
Prefix : +23
Now, when you convert it from left to right then you should have the knowledge of + that is yet to appear in the string. This looks simple in this particular example, now consider another example given below.
Example 2:
Infix : 2+3*4/5-6*7
Prefix : -+2/*345*67
Now, if you scan from left to right then when you scan 0th index of string then the program should have knowledge of - which is going to appear in 7th index of string which could be a hectic job.
So the safest way to do is to scan the string from right to left.
In the first step itself of converting an infix to prefix can someone explain in simple terms why should we reverse the string?
Without stating which algorithm you're referring to you leave us to guessing, but a simple guess would be:
Read the Prefix expression in reverse order (from right to left)
If the symbol is an operand, then push it onto the Stack. Otherwise if the symbol is an operator, then pop two operands from the Stack and create a string by concatenating the two operands and the operator between them: string = (operand1 + operator + operand2)
And push the resultant string back to Stack
Repeat the above steps until the end of Prefix expression.
At the end stack will have only 1 string i.e resultant string
Note that in step 2 operand1 is the first to be popped.
Obviously why you can't read the string left-to-right is rather obvious in this algorithm: the first you'd read is an operator and you wouldn't have any operands to pop.
The algorithm works because it's kind of transforms it to postfix and uses the algorithm for converting postfix to infix. "Kind of" because in reversing you don't only put the operator after the operand, you also reverse the order of the operands (which is why in step 2 you consider the top operand to be the left operand).
Is there any alternative method to convert?
Yes, as the above algorithm is basically to abstractly evaluate a postfix expression and express it as infix. You can do the same thing directly with a prefix expression.
Output an open parenthesis
Read the first token, if it's an operand output it and we're done. Otherwise:
Convert input prefix expression (recursively using this algorithm)
Output token read in 2
Convert input prefix expression (recursively using this algorithm)
Output an close parenthesis