1 / 12

Expressions: Operators and Operands

Expressions: Operators and Operands. Operators obey arity, associativity, and precedence int result = 2 * 3 + 5; // assigns 11 Operators are often overloaded for different types string name = first + last; // concatenation An lvalue gives a location; an rvalue gives a value

ajason
Télécharger la présentation

Expressions: Operators and Operands

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Expressions: Operators and Operands • Operators obey arity, associativity, and precedence int result = 2 * 3 + 5; // assigns 11 • Operators are often overloaded for different types string name = first + last; // concatenation • An lvalue gives a location; an rvalue gives a value • Left hand side of an assignment must be an lvalue • Prefix increment and decrement take and produce lvalues • Posfix versions (and &) take lvalues, produce rvalues • Beware accidentally using the “future equivalence” operator, e.g., if (i = j) instead of if (i == j) • Avoid type conversions if you can, and only use named casts (if you must explicitly convert types)

  2. Expressions as Program Inputs • E.g., what if we wanted prefix arithmetic, not infix ./prefix_adder + 8 + 9 10 • Can write a program to parse prefix expressions + 8 + 9 10 + + 8 9 10 • These are equivalent to their infix versions (8 + (9 + 10)) ((8 + 9) + 10) • Key idea: walk through expression, calculate value same result different order 1 1 + + 2 3 2 5 8 + + 10 4 5 3 4 9 8 10 9

  3. Exploring an Example Prefix Addition Program • A debugger helps us observe a program’s behavior • Step through (and into) functions • Watching the call stack and variable values • But, before we start using the fancy tools… • What do we expect the program to do? • How might the program fail? • Can we make predictions and test them? • Thinking: the most powerful way to explore or debug • Scientific method should guide what you do • Hypothesis  prediction  experiment  analysis (and repeat) • Tools can help you follow this disciplined approach faster

  4. How the Prefix Addition Program Can Fail • Too few arguments in expression ./prefix_adder + 8 + 9 • Cannot calculate result + 8 + 9 (needs another value to finish 2nd + operation) • Try this on your own in the studio, for practice 1 + 2 3 8 + 4 ??? 9

  5. Example Program Header File // prefix_adder.h // // author: Chris Gill cdgill@cse.wustl.edu // // purpose: Declarations for a simple prefix adder program, which // takes the command line arguments as a prefix addition // expression and computes an integer result. #ifndef PREFIX_ADDER_H #define PREFIX_ADDER_H // Function prototypes. void usage (char * program_name); int parse_and_compute (int & current_index, int last_index, char *argv[]); #endif /* PREFIX_ADDER_H */

  6. Example Program Source File / Usage Function // prefix_adder.cc // // author: Chris Gill cdgill@cse.wustl.edu // // purpose: definitions for a simple prefix adder program, which // takes the command line arguments as a prefix addition // expression and computes an integer result. #include "prefix_adder.h" #include <iostream> // For std output stream and manipulators. #include <string> // For standard C++ strings. #include <sstream> // For standard string streams. #include <cstring> // For C-style string functions // Helper function to print out the program's usage message. void usage (char * program_name) { cout << "Usage: " << program_name << " <argument> [<argument>]..." << endl << "Purpose: computes program arguments as prefix addition expression" << endl; }

  7. Example Program Main Function int main (int argc, char *argv[]) { // A few useful constants for argument positions const int minimum_arguments = 2; const int starting_index = 1; const int program_name_index = 0; if (argc < minimum_arguments || strcmp (argv[starting_index], "--help") == 0) { usage (argv[program_name_index]); return 1; } try { // Pass the current and last index to use, and the array, to the // expression parsing function, and store the result. int current_position = starting_index; int value = parse_and_compute (current_position, argc - 1, argv); // Print out the result, and return success value. cout << "The value calculated is " << value << endl; return 0; } catch (...) { cout << "caught exception" << endl; return -1; } }

  8. Example Program Parsing Function // Helper function to parse the input symbols and compute a value. int parse_and_compute (int & current_index, int last_index, char *argv[]) { // make sure we're still in the argument range if (current_index > last_index) { throw 1; } // look for a single-symbol addition operator if (strlen (argv[current_index]) == 1 && *(argv[current_index]) == '+') { int first_operand = parse_and_compute (++current_index, last_index, argv); int second_operand = parse_and_compute (current_index, last_index, argv); return first_operand + second_operand; } // treat anything else as an integer else { int result; istringstream i (argv[current_index++]); i >> result; return result; } }

  9. More Generally When Debugging Code May Help • When your program crashes • Finding out where it crashed • Examining program memory at that point • When a bug occurs in your program • Watching program variables • Identifying where a problem occurs (and why) • Tracing through a program’s behaviors • Learning what a program does • Good basic testing approach

  10. Another Motivation Debugging “Core” Dumps • A program dumps a memory image when it crashes • creates a file (called “core” on Linux) and then exits • this happens when a program receives certain signals: • Segmentation fault • accessed memory it does not own • or dereferenced a 0 pointer • Bus error • divided by zero • corrupted stack • Debuggers are very useful to examine “core” files • When your program crashes within Visual Studio • On Linux: gdb myprogram core

  11. Debugging on Various Platforms • We’ll use Visual Studio’s graphical debugger • Much more on this as we go through the semester • Set command line arguments in the project properties • It’s also good to know about common text-based tools • gdb • Debugger provided with the g++ compiler (e.g., on Linux) • Using –g switch embeds debug info during compilation • Runs well within emacs (Esc-X debug)

  12. Some Essential Debugging Commands • start (or restart) execution in the debugger • Visual Studio: F5 (Start Debugging) • gdb: run (also give its command line arguments) • execute one line, stepping into any functions • Visual Studio: F11 (Step Into) • gdb: step • execute one line, stepping over any functions • VS: F10 (Step Over) • gdb: next • set breakpoint at a line or function entry point • VS: F9 (Toggle Breakpoint) • gdb: break (can give file and line, function, etc.)

More Related