Pointer + Number - c++

I have this code:
How can i debug with printf?
char *string = "something";
short i;
i = strlen(string);
while (i-- && (*(string+i)==' ' || *(string+i)=='\0'));
*(string+i+1) = '\0' ;
What does this do?
*(string+i)

According to the C standard, the expression e1[e2] is by definition equivalent to *(e1+e2). So when you write
*(string + i)
it is equivalent
string[i]
This definition has an interesting side effect that it is actually correct to write 3[s] instead of s[3] as operator [] is commutative.

*(string+i) is string[i]. So *(string+i) == '\0' is the same as string[i] == 0.
This is because pointer + number is the same address as pointer + number * sizeof(type) (in your case string + i is the same a string + i * sizeof(char). When you index into an array arr[i] is the element at address arr + i * sizeof(type).
To debug with printf you simply insert printf statements and poke around the content of variables. For example:
char *string = "something";
short i;
i = strlen(string);
printf("Debug i = %d\n", i);

The postfix operator -- means that i will get evaluated and then decremented before the next sequence point.
The && operator has a sequence point between the left and right operand, so i-- occurs before the right operand is evaluated.
Therefore string+i refers to the value of the original i - 1.
*(string+i) is guaranteed to be completely equivalent with string[i]. The former is just a less readable form.
The code does a peculiar check. If a character is the null terminator, it adds another null terminator behind the first one. That doesn't make any sense. Only the check for space makes some sense.
I also doubt the true intention is to add a null after the space? Wouldn't you rather want to remove the space and end the string there? Seems like a mistake.
Also the code is inefficient, because if you count from the beginning to the end and encounter the first space there, you can stop iterating.
In other words, this code is just awful. You should replace it with something like this:
char* ptr = strchr(string, ' ');
if(ptr != NULL)
{
*ptr = '\0';
}

Related

Don't understand why while(*ptr++) enter while loop for 0 value (string terminator)

I have a problem with the following apperently trivial sample code:
(on visual studio 2015)
Please ignore the part with pointing to a literal constant, possible warnings or erros on the newwer compiler, that is not what I don't understand.
My problem is why it prints '0' and how the while loop works, tried using both debugger and printf. My understanding of the problem is this:
moves ptr to point at 'e'
checks content of ptr which is 'e' it is not 0 so it enters while loop
back to condition line, moves ptr to 'l'
checks *ptr, it is not 0, enters...
blah blah for the letters l, o
Then it increases ptr after 'o' and gets '\0', at which point by my logic it should NOT enter the loop, but i does, and no longer enters after one more step when it is pointing over the terminator at junk?!?
I looked over 2 other topics, this topic about operator precedence and this one about the while(*ptr) case going over the terminator, but I don't understand from the second WHY it enters the loop and thy it increases the pointer value afterwards? for what i understand the order is first increase pointer, then get the value with *
#include <cstdio>
#include<stdlib.h>
int main(void) {
char* str = "hello";
char* ptr = str;
char least = 127;
while (*ptr++) {
printf("%c-", *ptr);
least = ((*ptr) < (least)) ? (*ptr) : (least);
}
printf("%d\n", least);
}
Inside the loop you're not using the same character that you tested in the while condition.
Since ptr++ is a post-increment, it returns the current value of ptr and then increments it. So when ptr points to the o character, and you do
while (*ptr++)
it tests 'o', which is not zero, so it will enter the loop. But after the test it increments ptr to point to the next character, so now it points to '\0'. Then it prints this character and sets least to it.
You should increment the pointer after processing it. You can do this by moving ptr++ to the end of the loop body. Or you can use a for loop instead of while:
for (ptr = str; *ptr; ptr++)
The last printf call outputs the terminating zero of the string literal as an integer.
To make it clear consider a string literal with one actual character as for example "A".
Before the first iteration of the while loop
while (*ptr++)
{
printf("%c-", *ptr);
least = ((*ptr) < (least)) ? (*ptr) : (least);
}
the pointer ptr points to the character 'A' of the string literal. This expression
*ptr++
can be imagined like
char c = *ptr;
++ptr;
So the control passes to the body of the loop because 'A' is not equal to zero. Meantime the pointer ptr was increased after evaluation the condition. So now it points to the terminating zero '\0' of the string literal.
As 0 is less than 123 then the variable least gets the value 0.
least = ((*ptr) < (least)) ? (*ptr) : (least);
In the next iteration of the loop ptr still points to the terminating zero. So the control bypasses the body of the loop and the zero is outputted in the next statement after the loop.
From the C Standard (6.5.2.4 Postfix increment and decrement operators)
2 The result of the postfix ++ operator is the value of the
operand. As a side effect, the value of the operand object is
incremented (that is, the value 1 of the appropriate type is added to
it).

What happens due to & operator in the following case?

I have known, '&' as bitwise and as an operator to get memory address of a variable.
What happens in this case of the code?
res = res & (a[i]<[a[i+1]]);
If it is bitwise and , as far as I know the second condition is also checked,
but what if I used logical and instead of it , wouldn't it still be the same?
As first part is (say) false , second parts get checked comes true, but still res remains false.
Would it be same (for this case) to use logical and for this? or it has some other use (& operator) for this case?
int a[] {1,3,4,2};
int pos = 3;
bool res = true;
for(int i = 0; i < pos; i++)
res &= (a[i] < a[i + 1]);
(Sorry for bad english)
If it is bitwise and , as far as I know the second condition is also checked, but what if I used logical and instead of it , wouldn't it still be the same?
No. Boolean and (written as && or and) has short circuit evaluation - if left part is false right part is not evaluated at all. This allows to write code like this:
if( pointer != nullptr && pointer->value > 100 ) ...
if not short circuit evaluation this code would have UB. For example this code:
if( pointer != nullptr & pointer->value > 100 ) ...
has Undefined Behaviour when pointer is equal to nullptr
Would it be same (for this case) to use logical and for this? or it has some other use (& operator) for this case?
You cannot, as there is no &&= operator in C++. You can write:
res = res && (a[i] < a[i + 1]);
and that would have short circuit as well and compiler may even be smart enough to stop the loop, though I doubt and it should be expressed explicitly anyway:
bool res = true;
for(int i = 0; res && i < pos; i++)
res = a[i] < a[i + 1];
which does the same, but cleaner and more efficient.
Anyway when you need logical or boolean and you should use one to make your intention clear and avoid unexpected surprises.
Besides the short circuiting issue, If res == 2 then:
res & 1 will return 0 which will be interpreted as false.
res && 1 will return true.
Your question is not clear.
Okay, let's dive into your code.
Your given code is very clear. You are performing bitwise and for pos(3) times. For every loop you are comparing a[i] with a[i+1]. Please note that for the last loop, I mean when variable i becomes 3, then i+1 will be 4. And your array a[] doesn't have a[4]. It only has the last element having index 3.
So for bitwise and operation the value of res isn't predictable as a[4] isn't defined.
Now let's think about logical AND operation. For logical and your expression inside the for loop will once generate a false boolean value for a[i] < a[i+1] as your array a[] = {1,3,4,2}. Here 4>2 not 4<2. Hence it will generate false boolean value and your entire response will be false 'cause you know logical AND will be eventually 0 if one of the operands is false.
I think you have got this.

C++ - A better way to create a null terminated c-style string of specific size with same character

I am looking to create a null terminated c-style string where every character is - (hyphen). I am using the following block of code:
char output_str[n + 1];
std::fill(output_str, output_str + n, '-');
output_str[n + 1] = '\0';
1) Is there a smarter C++ way to do this?
2) When I print the size of the string the output is n, not n + 1. Am I doing anything wrong or is null character never counted?
Edit:
Please consider this block of code instead of the one above:
char output_str[n + 1];
std::fill(output_str, output_str + n, '-');
output_str[n] = '\0';
And please ignore the question regarding size.
Is there a smarter C++ way to do this?
Sure, use a std::string to do that:
std::string s(n,'-');
const char* cstyle = s.c_str();
1) Is there a smarter C++ way to do this?
Using the String class:
std::string output_str(n,'-');
In case you need a string in old C style
output_str.c_str(); // Returns a const char*
2) When I print the size of the string the output is n, not n + 1. Am I doing anything wrong or is null character never counted?
In your code, the N caracter is not added. If the array was pre-filled with zero, strlen function will return N.

Confused by a part of a code

There is a part of a code for "making the first letter of each word capitalized" I dont understand.
http://www.cplusplus.com/forum/beginner/117463/
std::string str = x;
str [0] = toupper (str[0]);
std::for_each(str.begin()+1, str.end(), printChars);
std::cout << str;
return 0;
}
Void printChars(char& c)
{
if( (*(&c - sizeof(char))) == " ")
c = toupper(c);
}
I understand it sets the first letter to capital always, and checks for each one in the string after.
But why does he use if((*(&c - sizeof(char))) == " ") and how does the * , & and setting it to blank work in this case?
how does ... work in this case?
It does not work. The program that you show is ill-formed and is not likely to compile.
Void printChars(char& c)
There is no type Void in C++. I suspect that you intended to write void instead.
(some_char_value) == " " // expression simplified by me
You may not compare a character to a string literal.
But why does he use if((*(&c - sizeof(char))) == " ")
He doesn't. He uses if( (*(&c - sizeof(char))) == ' ').
how does the & work in this case?
It is the address-of operator. It is used here to get a temporary pointer to the memory address of c.
how does the * work in this case?
It is the indirection operator. It is used here to get the character at the memory location &c - 1. Which is a character in str right before the character referred to by c.
and setting it to blank work in this case?
He doesn't set anything in the quoted expression. == is the equality comparison operator. He compares the values of the &c - 1 and the character literal ' '.
In english: He tests whether the character before c is space. In other words: He test whether c is the first character of a word.
This code is performing simple pointer arithmetic. The code you are asking about is using the reference operator & to grab the address of the variable c. Then performing subtraction of the size of a char to check if the char before c is a space if so it calls toUpper(). So for example
if the address of c is 100 then &c - sizeof(char) is checking the char at address 99 then the * is used to dereference the variable which allows for the comparison of the variable using == " ".

Need Help Understanding Recursive Prefix Evaluator

This is a piece of code I found in my textbook for using recursion to evaluate prefix expressions. I'm having trouble understanding this code and the process in which it goes through.
char *a; int i;
int eval()
{ int x = 0;
while (a[i] == ' ') i++;
if (a[i] == '+')
{ i++; return eval() + eval(); }
if (a[i] == '*')
{ i++; return eval() * eval(); }
while ((a[i] >= '0') && (a[i] <= '9'))
x = 10*x + (a[i++] - '0');
return x;
}
I guess I'm confused primarily with the return statements and how it eventually leads to solving a prefix expression. Thanks in advance!
The best way to understand recursive examples is to work through an example :
char* a = "+11 4"
first off, i is initialized to 0 because there is no default initializer. i is also global, so updates to it will affect all calls of eval().
i = 0, a[i] = '+'
there are no leading spaces, so the first while loop condition fails. The first if statement succeeds, i is incremented to 1 and eval() + eval() is executed. We'll evaluate these one at a time, and then come back after we have our results.
i = 1, a[1] = '1'
Again, no leading spaces, so the first while loop fails. The first and second if statements fail. In the last while loop, '1' is between 0 and 9(based on ascii value), so x becomes 0 + a[1] - '0', or 0 + 1 = 1. Important here is that i is incremented after a[i] is read, then i is incremented. The next iteration of the while loop adds to x. Here x = 10 * 1 + a[2] - '0', or 10 + 1 = 11. With the correct value of x, we can exit eval() and return the result of the first operand, again here 11.
i = 2, a[2] = '4'
As in the previous step, the only statement executed in this call of eval() is the last while loop. x = 0 + a[2] - '0', or 0 + 4 = 4. So we return 4.
At this point the control flow returns back to the original call to eval(), and now we have both values for the operands. We simply perform the addition to get 11 + 4 = 15, then return the result.
Every time eval() is called, it computes the value of the immediate next expression starting at position i, and returns that value.
Within eval:
The first while loop is just to ignore all the spaces.
Then there are 3 cases:
(a) Evaluate expressions starting with a + (i.e. An expression of the form A+B which is "+ A B" in prefix
(b) Evaluate expressions starting with a * (i.e. A*B = "* A B")
(c) Evaluate integer values (i.e. Any consecutive sequence of digits)
The while loop at the end takes care of case (c).
The code for case (a) is similar to that for case (b). Think about case (a):
If we encounter a + sign, it means we need to add the next two "things" we find in the sequence. The "things" might be numbers, or may themselves be expressions to be evaluated (such as X+Y or X*Y).
In order to get what these "things" are, the function eval() is called with an updated value of i. Each call to eval() will fetch the value of the immediate next expression, and update position i.
Thus, 2 successive calls to eval() obtain the values of the 2 following expressions.
We then apply the + operator to the 2 values, and return the result.
It will help to work through an example such as "+ * 2 3 * 4 5", which is prefix notation for (2*3)+(4*5).
So this piece of code can only eat +, *, spaces and numbers. It is supposed to eat one command which can be one of:
- + <op1> <op2>
- * <op1> <op2>
<number>
It gets a pointer to a string, and a reading position which is incremented as the program goes along that string.
char *a; int i;
int eval()
{ int x = 0;
while (a[i] == ' ') i++; // it eats all spaces
if (a[i] == '+')
/* if the program encounters '+', two operands are expected next.
The reading position i already points just before the place
from which you have to start reading the next operand
(which is what first eval() call will do).
After the first eval() is finished,
the reading position is moved to the begin of the second operand,
which will be read during the second eval() call. */
{ i++; return eval() + eval(); }
if (a[i] == '*') // exactly the same, but for '*' operation.
{ i++; return eval() * eval(); }
while ((a[i] >= '0') && (a[i] <= '9')) // here it eats all digit until something else is encountered.
x = 10*x + (a[i++] - '0'); // every time the new digit is read, it multiplies the previously obtained number by 10 and adds the new digit.
return x;
// base case: returning the number. Note that the reading position already moved past it.
}
The example you are given uses a couple of global variables. They persist outside of the function's scope and must be initialized before calling the function.
i should be initialized to 0 so that you start at the beginning of the string, and the prefix expression is the string in a.
the operator is your prefix and so should be your first non-blank character, if you start with a number (string of numbers) you are done, that is the result.
example: a = " + 15 450"
eval() finds '+' at i = 1
calls eval()
which finds '1' at i = 3 and then '5'
calculates x = 1 x 10 + 5
returns 15
calls eval()
which finds '4' at i = 6 and then '5' and then '0'
calclulates x = ((4 x 10) + 5) x 10) + 0
returns 450
calculates the '+' operator of 15 and 450
returns 465
The returns are either a value found or the result of an operator and the succeeding results found. So recursively, the function successively looks through the input string and performs the operations until either the string ends or an invalid character is found.
Rather than breaking up code into chunks and so on, i'll try and just explain the concept it as simple as possible.
The eval function always skips spaces so that it points to either a number character ('0'->'9'), an addition ('+') or a multiply ('*') at the current place in the expression string.
If it encounters a number, it proceeds to continue to eat the number digits, until it reaches a non-number digit returning the total result in integer format.
If it encounters operator ('+' and '*') it requires two integers, so eval calls itself twice to get the next two numbers from the expression string and returns that result as an integer.
One hair in the soup may be evaluation order, cf. https://www.securecoding.cert.org/confluence/display/seccode/EXP10-C.+Do+not+depend+on+the+order+of+evaluation+of+subexpressions+or+the+order+in+which+side+effects+take+place.
It is not specified which eval in "eval() + eval()" is, well, evaluated first. That's ok for commutative operators but will fail for - or /, because eval() as a side effect advances the global position counter so that the (in time) second eval gets the (in space) second expression. But that may well be the (in space) first eval.
I think the fix is easy; assign to a temp and compute with that:
if (a[i] == '-')
{ i++; int tmp = eval(); return tmp - eval(); }