Here’s another reason to invest solid hours to build c-str manipulation skill — strings are the most important object used in interviews, more than integers. Integers have zero operational complexity, but look at the string operational complexity in http://bigblog.tanbin.com/2008/05/c-string-complete-cheat-sheet.html
As written elsewhere on this blog, i still prefer c-str. Some things c-str can do more than std::string, but I feel there’s nothing that c-str can’t do, to the extent that BASIC can do everything c++ can. C-str is a complete and proven toolkit. For everyday coding (+ coding tests), I feel the family of c-string functions (about 20) together qualify as a rather complete toolkit, albeit primitive by today’s standard.
 some justifications
* many teams don’t like std::string and want a optimized string, invariably based on c-str.
* many legacy code and system calls use C, ruling out std::string.
Nevertheless, std::string does add value in terms of convenience, though the more fundamental feature added by std::string is memory management.
1) convenience – integration with c++ iostreams
2) convenience – integration with STL
3) convenience – c-string as a raw-array has many syntax constraints. std::string helps.
How important? So low-level! I feel precise grasp gives us confidence. There are quite a lot of nuances due to this fundamental difference.
int arr = …
int* ptr = …;
[[headfirst C]] P79 clearly explains that compiler will allocate stack memory for a variable ptr but not for arr. Basically, the
“arr” variable doesn’t exist in the final executable.
(Assuming a 32bit) If you look at the size of the stack frame, you find 4 bytes for “ptr” and 33*2 bytes for “arr”. No allocation for the “arr” variable! Compiler allocates 4 bytes for the ptr VARIABLE “ptr” partly because we can later reseat this pointer. In contrast, the “arr” name is a not reseatable and a permanent alias for the address of array object. Every occurence of “arr” is replaced (by compiler) with the actual address of the array object.
arr = anotherArray;// won’t compile.
On P59, the book points out another key difference between array Name vs ptr Variable
Taking the address of “ptr” gives you the address of the 4-byte ptr VARIABLE. So suppose ptr points to address 0x0197. &ptr may be 0xb762. In contrast,
&arr == arr // Both expressions evaluate to an address (like 0xb755) of the array OBJECT. There’s no separate allocation or separate address for the “arr” variable (non-existent). The “arr” is just a name in source code.
Backgrounder — The traditional meaning of a “sell-side” is basically a player who makes a living
– by commission or
– by earning bid-ask spread (market makers),
– but no insurance premium.
Such a player provides liquidity to the market and seldom consumers liquidity. In so doing they provide a valuable service to the market and are rewarded. In a sense, they sell liquidity.
I now think of fx options as even more like insurance than equity options. There's economic need for fx options. Demand comes from mostly (MNC) corporations. They buy this insurance because they need protection.
Since fx options are insurance, it's natural to classify the participants as sellers and buyers. I guess some big players in this market stay primarily on one side only. (Some banks may need to pay insurance premium just for hedging.) If that's true then the “sell-side” concept can be adjusted to mean players who make a living selling insurance who seldom buys the same insurance except for hedging.
The mainstream sellers are banks. If the interbank bid-ask vol spread is narrow, then these sellers will have little restraint from frequent buying/selling.
Compared to corporations, is there an even bigger category of buyers in the fxo market? I don't think so. I have no statistics, but I believe corporations are the most stable client base for the banks.
I think the commodity options (or options on futures) market isn't that active, but these option sellers are, likewise, insurers to provide for an economic need.
By “static” I mean global variables or local static variables. These are Objects with addresses, not mere symbols in source code. Note Some static objects are _implicitly_ static — P221 effC++.
Rule 1: uninitialized local and class fields of primitive types (char, float…) aren’t automatically initialized. See [[programming]] by Stroustrup.
Rule 2: uninitialized statics are automatically initialized to 0 bits at a very early stage of program loading. See
Rule 3: all class instances are “initialized”, either explicitly, or implicitly via default ctor. Beware. Reconsider Rule 1 — is a field of primitive type of the class initialized? I don’t think so. Therefore, “initialized” means a ctor is called on the new-born instance, but not all fields therein are necessarily initialized. I’d say the ctor can simply ignore a primitive-typed field.
Uninitialized static Objects (stored in BSS segment) don’t take up space in object file. Also, by grouping all the symbols that are not explicitly initialized together, they can be easily zeroed out at once. See
Any static Object explicitly initialized by programmer is considered an “initialized” static object and doesn’t go into BSS.
P136 [[understanding and using c pointers]] uses a real example to confirm that a pointer field in a C struct is uninitialized. C has no ctor!
P261 [[programming]] by Stroustrup has a half-pager summary
* globals are default-initialized
* locals and fields are truly uninitialized …
** … unless the data type is a custom class having a default ctor. In that case, you can safely declare the variable without initialization, and content will be a pre-set value.
See also post about MSDN overview on mem mgmt…
- “delete” risk: too early -> stray pointer
- “delete” risk: too “late” -> leak. You will see steadily growing memory usage
- “delete” risk: too many times -> double free
- … these risks are resolved in java and dotnet.
For all simple scenarios, I feel the default and standard idiom to program the delete is RAII. This means the delete is inside a dtor, which in turn means there’s a wrapper class, perhaps some smart ptr class.
It also means we create stack instances of
– the wrapper class
– a container holding the wrapper objects
– an umbrella holding the wrapper object
Should every departure/deviation be documented?
I feel it’s not a best idea to pass a pointer into some cleanup function, and inside the function, delete the passed-in pointer. What if the pointee is a pointee already deleted, or a pointee still /in active service/, or a non-heap pointee, or a pointee embedded in a container or umbrella… See P52 [[safe c++]]
If a (possibly static) method or getter has “yield”, then I call it (loosely) a “yield method” — officially an “iterator-method”. A yield method must return aa) IEnumerator or bb) IEnumerable.
–aa) If a “yield-method” has return type IEnumerator, then exactly 1 unnamed class generated. The yield-method return value is an instance of this unnamed class.
* This class implements IEnumerator
–bb) If a “yield-method” has return type IEnumerable, then 2 unnamed classes. The first (outside) class implements IEnumerable, so the yield-method return value is this type. This outside class implements the mandatory GetEnumerator() method returning an IEnumerator. GetEnumerator() return value is an instance of the other (inside) class.
* the 1st class implements IEnumerable
* the 2nd class implements IEnumerator
Here's a potential confusion. Say you write an IEnumerable subclass. In it you write a GetEnumerator() returning an IEnumerator. Is this the aa case or the bb case? Actually aa.
Q1: when is such a class instantiated?
A: every invocation of the yield method would instantiate an instance of 1 or 2 classes. The IEnumerator object is stateful, so you hold on to that object throughout the iteration. You don't call the yield method 55 times to hit the 55 items — you call Current/MoveNext 55 times.
Q2: but when exactly is the yield method invoked?
A: Invoked at the initialization of the foreach. The only way to use a yield-method is a foreach loop.
See P101 [[c# precisely]]
Without a context, these identifiers all look indistinguishable.
Argument passed in? arg_
Local temp variables? tmp_
Fields? Just qualify it with this.field1 or MyClass.field1
Events? Just qualify ith with this.event1 or MyClass.event1
Properties? CapitalizeFirstLetter. Actually, these are primarily used outside host class. In such cases they are fairly identifiable.
I find this algorithm extremely simple but not easy to recognize. The extreme simplicity indicates some important/valuable tip but not sure what.
Write a scheduler for a single gym equipment(like a room). Every morning at 8am before start of day, we receive a batch file containing all booking requests for that day. We run the scheduler once, and all accepted bookings are confirmed and finalized. Each request is identified by a pair of start/end times on the current day. No 2 requests share the same start/end times (perhaps because the duplicates are already filtered out). Exercise duration is in blocks of 1 minute. We earn $1 rental for each session regardless of duration. Optimization goal is to allocate as many sessions as possible. We don’t care idle time; it doesn’t cost us. Let’s say the candidate for the “optimal” allocation plan is PlanK.
(I feel this is not a dynamic programming algorithm, but a greedy algorithm.)
If there’s a last-minute user (4.59pm – 5pm, let’s call it AA), then it’s always good to accept. This last minute user AA doesn’t block others. AA is a minimum-hindrance session.
If PlanK ends with any other session (call it BB), BB surely starts before 4.59pm. BB is a bigger hindrance than AA. If we replace BB with the last-minute user AA, we would produce a “safer” plan – PlanL. PlanL is at least as optimal as PlanK, and can potentially /accommodate/ additional sessions. Therefore PlanK without AA isn’t the optimal. The optimal plan ought to include the last-minute allocation.
That’s the key to the optimization. The last-to-begin session has minimum hindrance and should always be selected. After that selection, eliminate all requests that are now hindered. Then among the remaining requests, look for the last-to-begin.
Exploiting symmetry, you can reverse the algorithm by picking the first-to-end session.
Too many cross-referencing in the commanding architecture. I'd say ignore the conceptual and focus on a typical implementation. Even
at the implementation levle, Commanding involves a web of references — non-trivial.
command source (typically a visual) often not always defines a command property and a command target property.
command target (typically a visual) often not always defineds a command binding and command handlers/reactors.
ostringstream. See [[essential c++]] P202
ostringstream can convert “everything” to string.
ostringstream can concat.
ostringstream can produce string or c_str.
Practical and Useful for coding tests.
As you can guess, the opposite, istringstream class, can extract and parse from string to many data types.