This question already has answers here:
What does the operation c=a+++b mean?
(9 answers)
Closed 9 years ago.
#include <stdio.h>
int main()
{
int a=8,b=9,c;
c=a+++b;
printf("%d%d%d\n",a,b,c);
return 0;
}
The program above outputs a=9 b=9 and c=17. In a+++b why is the compiler takes a++ and then adds with b. Why is it not taking a + and
++b? Is there a specific name for this a+++b. Please help me to understand.
I like the explanation from Expert C Programming:
The ANSI standard specifies a convention that has come to be known as
the maximal munch strategy. Maximal munch says that if there's more
than one possibility for the next token, the compiler will prefer to
bite off the one involving the longest sequence of characters. So the
example will be parsed
c = a++ + b;
Read Maximum Munch Principle
"maximal munch" or "longest match" is the principle that when creating some construct, as much of the available input as possible should be consumed.
Every compiler has a tokenizer, which is a component that parses a source file into distinct tokens (keywords, operators, identifiers etc.). One of the tokenizer's rules is called "maximal munch", which says that the tokenizer should keep reading characters from the source file until adding one more character causes the current token to stop making sense
Order of operations in C dictate that unary operations have higher precedence than binary operations.
You could use a + (++b) if you wanted b to be incremented first.
Related
I have been tasked with studying and modifying a C program. Generally, I write code in pl/sql, but not C. I have been able to decipher most of the code, but the program flow is still eluding me. After looking up several C references guides, I am not understanding how the C code works. I'm hoping someone here can answer a few syntax questions and tell me what each statement is trying to do.
Here is one sample, with my guesses below.
input(ask_fterm,TM_NLS_Get("0004","FROM TERM: "),6,ALPHA);
if ( !*ask_fterm ) goto opt_fterm;
tmstrcpy(fterm,ask_fterm);
goto nextparmb;
opt_fterm:
tmstrcpy(parm_no,_TMC("02"));
sel_optional_ind(FIRST_ROW);
if ( compare(rpt_optional_ind,_TMC("O"),EQS) ) goto nextparmb;
goto missing_parms;
First, I don't understand !*. What does the exclamation asterisk combination?
Second I assume that if must be ended with endif, unless it is on a single line?
Third tmstrcopy() apparently copies the value of the 2nd parameter into the 1st parameter?
I also have several parameters which I don't understand. I'm hoping someone gives me a hint.
tmstrcpy(valid_ind,_TMC("N"));
input(ask_toterm,TM_NLS_Get("0005","TO TERM: "),6,ALPHA);
I don't know where to find _TMC and TM_NLS_Get.
First, I don't understand !*. What does the exclamation asterisk combination?
That's two separate operators. ! is logical negation. Unary * is for dereferencing a pointer. Put together, they each have their separate effect, so !*ask_fterm means determine the value of the object to which pointer ask_fterm points (this is *); if that value is 0 then the result is 1, else the result is 0 (this is !). If ask_fterm is a pointer to the first character of a string, then that's a check for whether the string is empty (zero-length), because C strings are terminated by a character with value 0.
Second I assume that if must be ended with endif, unless it is on a single line?
There is no endif in C. An if construct controls exactly one statement, but that can be and often is a compound one (which you can recognize by the { and } delimiters enclosing it). There may also be an else clause, also controlling exactly one statement, which can be a compound one.
Third tmstrcopy() apparently copies the value of the 2nd parameter into the 1st parameter?
That appears to be a user-defined function. It is certainly not from the C standard library. If I were to guess based on the name and usage, I would guess that it copies a trimmed version of the string to which the right-hand argument points into the space to which the left-hand argument points.
I don't know where to find _TMC and TM_NLS_Get.
Those are not standard C features. Possibly they are recognized directly by your C implementation, or possibly they are macros defined earlier in the file or in one of the header files it includes.
I'm new to c language. Did "precedence" determine the grouping of sub expression. Can you explain how sub grouping works?
Explain why the strange output come when I do i=7; ++i+++i+++i; shows error while just putting space between ++i + ++i + ++i; don't give any error and answer is 22 in Gcc; how this output come?
I checked books also most of them have some "precedence" order and than some" associativity rules", no clear explanation about sub grouping.
can you explain me what to do whenever I saw these kind of mix expression. Almost every c language aptitude ask such type of question.
This is a duplicate of a few questions on SO, but here goes.
Maximal Munch
The C parser will try to grab as many characters as it can to split your program into tokens. In ++i+++i+++i; the parser splits the string into:
++
i
++
+
i
++
+
i
;
It then sees that preincrement (token 1) and postincrement (token 3) are both applied to the first i (token 2), and reports an error. The parser does not backtrack and reparse the string to use + for token 3 and ++ for token 4. If the compiler had the license to do this, a malicious program could take arbitrarily-long time to parse.
Multiple Side-Effects
C and its family of languages defines a sequence point as a point in a statement's execution where all variables have definite values. It is undefined behavior to have more than one side-effect occur to a variable between sequence points. Simplify your example a bit. What could this code do? I have changed a preincrement to a predecrement so I can talk about them easier.
int j = ++i + --i;
Increment i.
Use the incremented value for the first summand.
Decrement i.
Use the decremented value for the second summand.
Add the two values and assign to j.
However, the C standard does not fix the order of these effects except that step 1 must precede step 2, step 3 must precede step 4, and step 5 must be last. What your compiler does need not be what another compiler does, and it need not be consistent, even in the same program. As the joke in the Jargon File goes:
nasal demons, n.
Recognized shorthand on the Usenet group comp.std.c for any unexpected behavior of a C
compiler on encountering an undefined construct. During a discussion on that group in early
1992, a regular remarked “When the compiler encounters [a given undefined construct] it is
legal for it to make demons fly out of your nose” (the implication is that the compiler may
choose any arbitrarily bizarre way to interpret the code without violating the ANSI C
standard). Someone else followed up with a reference to “nasal demons”, which quickly
became established. The original post is web-accessible at http://groups.google.com/groups?hl=en&selm=10195%40ksr.com.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
What does the 'k' prefix indicate in Apple's APIs?
Objective C - Why do constants start with k
For example, the result codes defined for Audio Format Services:
kAudioFormatUnspecifiedError
kAudioFormatUnsupportedPropertyError
etc...
What does that leading k stand for? I've always assumed key, since such constants are often used as the keys in dictionaries, but those result codes are an example of where the constant is just a return value, not (as far as a client of the API can determine) a key.
I imagine that it merely stands for 'k'onstant, where 'k' is used because 'c' is already commonly used to indicate class or in Hungarian notation character.
The usage has historical precedent; early pocket calculators used 'k' to indicate constant mode (where repeated operation of = repeated the last operation) because 'c' was used for clear.
You can find the answer here.
Answer one
Constant names (#defines, enums, const local variables, etc.) should start with a
lower-case k and then use mixed case to delimit words, i.e.
kInvalidHandle, kWritePerm.
Though a pain to write, they are absolutely vital to keeping our code
readable. The following rules describe what you should comment and
where. But remember: while comments are very important, the best code
is self-documenting. Giving sensible names to types and variables is
much better than using obscure names and then trying to explain them
through comments.
But it has since been removed in the live version of the document. It
should be noted that it goes against the the Official Coding Guidelines
for Cocoa from Apple.
Cocoa coding guidelines
It was the coding standard left over when Apple used pascal. K was the prefix as opposed to all caps for other C languages.
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Char to int conversion in C.
I remember learning in a course a long time ago that converting from an ASCII char to an int by subtracting '0' is bad.
For example:
int converted;
char ascii = '8';
converted = ascii - '0';
Why is this considered a bad practice? Is it because some systems don't use ASCII? The question has been bugging me for a long time.
While you probably shouldn't use this as part of a hand rolled strtol (that's what the standard library is for) there is nothing wrong with this technique for converting a single digit to its value. It's simple and clear, even idiomatic. You should, though, add range checking if you are not absolutely certain that the given char is in range.
It's a C language guarantee that this works.
5.2.1/3 says:
In both the source and execution basic character sets, the value of each character after 0 in the above list [includes the sequence: 0,1,2,3,4,5,6,7,8,9] shall be one greater that the value of the previous.
Character sets may exist where this isn't true but they can't be used as either source or execution character sets in any C implementation.
Edit: Apparently the C standard guarantees consecutive 0-9 digits.
ASCII is not guaranteed by the C standard, in effect making it non-portable. You should use a standard library function intended for conversion, such as atoi.
However, if you wish to make assumptions about where you are running (for example, an embedded system where space is at a premium), then by all means use the subtraction method. Even on systems not in the US-ASCII code page (UTF-8, other code pages) this conversion will work. It will work on ebcdic (amazingly).
This is a common trick taught in C classes primarily to illustrate the notion that a char is a number and that its value is different from the corresponding int.
Unfortunately, this educational toy somehow became part of the typical arsenal of most C developers, partially because C doesn't provide a convenient call for this (it is often platform specific, I'm not even sure what it is).
Generally, this code is not portable for non-ASCII platforms, and for future transitions to other encodings. It's also not really readable. At a minimum wrap this trick in a function.
(in c90) (linux)
input:
sqrt(2 - sin(3*A/B)^2.5) + 0.5*(C*~(D) + 3.11 +B)
a
b /*there are values for a,b,c,d */
c
d
input:
cos(2 - asin(3*A/B)^2.5) +cos(0.5*(C*~(D)) + 3.11 +B)
a
b /*there are values for a,b,c,d */
c
d
input:
sqrt(2 - sin(3*A/B)^2.5)/(0.5*(C*~(D)) + sin(3.11) +ln(B))
/*max lenght of formula is 250 characters*/
a
b /*there are values for a,b,c,d */
c /*each variable with set of floating numbers*/
d
As you can see infix formula in the input depends on user.
My program will take a formula and n-tuples value.
Then it calculate the results for each value of a,b,c and d.
If you wonder I am saying ;outcome of program is graph.
/sometimes,I think i will take input and store in string.
then another idea is arise " I should store formula in the struct"
but ı don't know how I can construct
the code on the base of structure./
really, I don't know way how to store the formula in program code so that
I can do my job.
can you show me?
/* a,b,c,d is letters
cos,sin,sqrt,ln is function*/
You need to write a lexical analyzer to tokenize the input (break it into its component parts--operators, punctuators, identifiers, etc.). Inevitably, you'll end up with some sequence of tokens.
After that, there are a number of ways to evaluate the input. One of the easiest ways to do this is to convert the expression to postfix using the shunting yard algorithm (evaluation of a postfix expression is Easy with a capital E).
You should look up "abstract syntax trees" and "expression trees" as well as "lexical analysis", "syntax", "parse", and "compiler theory". Reading text input and getting meaning from it is quite difficult for most things (though we often try to make sure we have simple input).
The first step in generating a parser is to write down the grammar for your input language. In this case your input language is some Mathematical expressions, so you would do something like:
expr => <function_identifier> ( stmt )
( stmt )
<variable_identifier>
<numerical_constant>
stmt => expr <operator> stmt
(I haven't written a grammar like this {look up BNF and EBNF} in a few years so I've probably made some glaring errors that someone else will kindly point out)
This can get a lot more complicated depending on how you handle operator precedence (multiply and device before add and subtract type stuff), but the point of the grammar in this case is to help you to write a parser.
There are tools that will help you do this (yacc, bison, antlr, and others) but you can do it by hand as well. There are many many ways to go about doing this, but they all have one thing in common -- a stack. Processing a language such as this requires something called a push down automaton, which is just a fancy way of saying something that can make decisions based on new input, a current state, and the top item of the stack. The decisions that it can make include pushing, popping, changing state, and combining (turning 2+3 into 5 is a form of combining). Combining is usually referred to as a production because it produces a result.
Of the various common types of parsers you will almost certainly start out with a recursive decent parser. They are usually written directly in a general purpose programming language, such as C. This type of parser is made up of several (often many) functions that call each other, and they end up using the system stack as the push down automaton stack.
Another thing you will need to do is to write down the different types of words and operators that make up your language. These words and operators are called lexemes and represent the tokens of your language. I represented these tokens in the grammar <like_this>, except for the parenthesis which represented themselves.
You will most likely want to describe your lexemes with a set of regular expressions. You should be familiar with these if you use grep, sed, awk, or perl. They are a way of describing what is known as a regular language which can be processed by something known as a Finite State Automaton. That is just a fancy way of saying that it is a program that can make a decision about changing state by considering only its current state and the next input (the next character of input). For example part of your lexical description might be:
[A-Z] variable-identifier
sqrt function-identifier
log function-identifier
[0-9]+ unsigned-literal
+ operator
- operator
There are also tools which can generate code for this. lex which is one of these is highly integrated with the parser generating program yacc, but since you are trying to learn you can also write your own tokenizer/lexical analysis code in C.
After you have done all of this (it will probably take you quite a while) you will need to have your parser build a tree to represent the expressions and grammar of the input. In the simple case of expression evaluation (like writing a simple command line calculator program) you could have your parser evaluate the formula as it processed the input, but for your case, as I understand it, you will need to make a tree (or Reverse Polish representation, but trees are easier in my opinion).
Then after you have read the values for the variables you can traverse the tree and calculate an actual number.
Possibly the easiest thing to do is use an embedded language like Lua or Python, for both of which the interpreter is written in C. Unfortunately, if you go the Lua route you'll have to convert the binary operations to function calls, in which case it's likely easier to use Python. So I'll go down that path.
If you just want to output the result to the console this is really easy and you won't even have to delve too deep in Python embedding. Since, then you only have to write a single line program in Python to output the value.
Here is the Python code you could use:
exec "import math;A=<vala>;B=<valb>;C=<valc>;D=<vald>;print <formula>".replace("^", "**").replace("log","math.log").replace("ln", "math.log").replace("sin","math.sin").replace("sqrt", "math.sqrt").replace("cos","math.cos")
Note the replaces are done in Python, since I'm quite sure it's easier to do this in Python and not C. Also note, that if you want to use xor('^') you'll have to remove .replace("^","**") and use ** for powering.
I don't know enough C to be able to tell you how to generate this string in C, but after you have, you can use the following program to run it:
#include <Python.h>
int main(int argc, char* argv[])
{
char* progstr = "...";
Py_Initialize();
PyRun_SimpleString(progstr);
Py_Finalize();
return 0;
}
You can look up more information about embedding Python in C here: Python Extension and Embedding Documentation
If you need to use the result of the calculation in your program there are ways to read this value from Python, but you'll have to read up on them yourself.
Also, you should review your posts to SO and other posts regarding Binary Trees. Implement this using a tree structure. Traverse as infix to evaluate. There have been some excellent answers to tree questions.
If you need to store this (for persistance as in a file), I suggest XML. Parsing XML should make you really appreciate how easy your assignment is.
Check out this post:
http://blog.barvinograd.com/2011/03/online-function-grapher-formula-parser-part-2/
It uses ANTLR library for parsing math expression, this one specifically uses JavaScript output but ANTLR has many outputs such as Java, Ruby, C++, C# and you should be able to use the grammar in the post for any output language.