Difference between ptr++ and ptr + 1 - c

I wrote a code to reverse a string using recursion. When I run it, I get a segmentation error.
#include <stdio.h>
void _print_rev_recursion(char *s);
int main() {
_print_rev_recursion("string reversal");
return (0);
}
void _print_rev_recursion(char *s)
{
if (!*s)
return;
_print_rev_recursion(s++);
putchar(*s);
}
When I changed s++ to s + 1, the code works.
I thought both s++ and s+1 mean the same thing. I need clarification please.
This is the code that works:
#include <stdio.h>
void _print_rev_recursion(char *s);
int main() {
_print_rev_recursion("string reversal");
return (0);
}
void _print_rev_recursion(char *s)
{
if (!*s)
return;
_print_rev_recursion(s + 1);
putchar(*s);
}

I thought both s++ and s+1 mean the same thing
They do not.
s++ changes s while s+1 does not.
The values of the expressions are also different. s++ has the value of s prior to the increment. s+1 has the value of s + 1.

In case of s++ the increment happens after the function is called, so you get infinite recursion. s+1 makes the increment happen before the recursive call.

Related

Confused about increment operator in C

I've written a program in C to create a basic stack using an array. It works as expected, but there is something I'm very confused about. On the first line of the push method, I increment the value of *top_ptr, which is a pointer to the variable top, using the syntax
*top_ptr = *top_ptr+1. When I try to replace this line with *top_ptr++, which I think is more concise and meant the same thing, I get a warning that says Wunused variable, and a segmentation fault error when running it. The warning message from my terminal, word for word, is
warning: expression result unused [-Wunused-value]
*top_ptr++;
^~~~~~~~~~
and my exact error message from the terminal is:
zsh: segmentation fault ./stacks/arrayi
When I run the program with the current program, my output is what I expect: 1 2 3 %
My code is below. Again, the line I'm confused about is the first line of the push method, which is line 17. If you answer this, then thank you for your time and consideration.
#include <stdio.h>
#define MAX_SIZE 101
void push(int *, int *, int);
void print(int *, int *);
int main() {
int top = -1;
int *top_ptr = &top;
int arr[MAX_SIZE];
push(arr, top_ptr, 1);
push(arr, top_ptr, 2);
push(arr, top_ptr, 3);
print(arr, top_ptr);
}
void push(int *array, int *top_ptr, int x) {
*top_ptr = *top_ptr + 1;
array[*top_ptr] = x;
}
void print(int *array, int *top_ptr) {
for (int i = 0; i <= *top_ptr; i++) {
printf("%d ", array[i]);
}
}
*top_ptr++ is *(top_ptr++), which is wrong because it changes top_ptr, which is not what you want to do.
You want (*top_ptr)++.
The compiler warns you the expression result is unused because, after (top_ptr++), the * fetches the value that (top_ptr++) points to, but nothing is done with that value. That is suspicious, so the compiler warns you you have told it to get a value but not to do anything with it.
In contrast, with (*top_ptr)++, it does not warn you because the ++ modifies the thing that (*top_ptr) points to, so the expression finishes with a useful action.
you should be doing
(*top_ptr)++;
that bracket is important. if u don't give the bracket then basically it'll be executed like
*(top_ptr++);
i.e. at first the pointer top_ptr will be incremented and then it'd be deferenced. that's why it's giving you segmentation fault.
(and the value pointed by top_ptr won't be incremented)

Why is this call to a pure function with a string literal argument not optimized to a constant value?

I have a simple function which counts the letter t in a string:
#include <stdio.h>
#include <string.h>
static int count_t_letters(const char *t) {
int r;
r = 0;
while(*t) {
if(*t == 't') {
++r;
}
++t;
}
return r;
}
int main() {
printf("%i", count_t_letters("test"));
}
here's the optimization I was expecting:
int main() {
printf("%i", 2);
}
Why is this simple function not optimized like I expected in neither gcc nor clang? (godbolt)
What I figured out so far:
Simple functions with integer pointer arguments are optimized to a constant
(godbolt)
Using C++ with a constexpr enables this optimization (godbolt)
Clang is able to do such an optimization if there is no ++t after the if (godbolt)
Because you're creating side effects by modifying the pointer.
If instead of incrementing t you simply use a normal index int and increment that instead, then gcc has no trouble optimizing it as you desire.
Modifying the pointer has side effects.
Another way, simply make a copy of the pointer, and modify the copy. Again it optimizes.

printBackward recursion doesn't print first element of array when using operator ++

I wanna print an integer array backward and detect that when using ++ instead of "startPos + 1" result comes to lose the first element of array. I debugged to understand the problem, but the recursion works so strange. Can you explain what the problem is? Thank you very much.
#include <stdio.h>
#define SIZE 10
void printBackward(const int[], const int size, int startPosition);
int main(void)
{
const int a[SIZE] = {1,3,5,7,9,10,13,15,17,19};
printBackward(a,SIZE,0);
puts("");
}
void printBackward(const int a[SIZE], const int size, int startPos)
{
if(startPos < size)
{
printBackward(a,size,++startPos); // work wrongly with ++startPos
//printBackward(a,size,startPos + 1); // work properly
printf_s("%4d",a[startPos]);
}
}
Passing startPos + 1 to the function does not change the value of startPos. However, ++startPos actually increments the value of startPos. The two are not interchangeable.

how can you check if a void function ran successfully with printf?

A friend told me there is a way to check with printf without modifying the original void function.
But I can't see how you can do it.
#include<stdio.h>
void test()
{
int a = 1;
int b = a;
}
main()
{
printf("%d",test());
}
I kept getting
error: invalid use of void expression
Is there a way to do it?
I see from your edit that you want to do this without modifying the function. You can employ the comma operator to make the function call in a printf:
#include <stdio.h>
void test()
{
int a = 1;
int b = a;
}
main()
{
printf("%d\n", (test(), 0));
// or even this, to be more explicit:
printf("%s\n", (test(), "test() was called."));
}
The comma operator evaluates the first operand - in this case your function call - and discards the result, then evaluates the second operand and the result is the result of the entire expression.
An example would be to pass memory pointer into the void function and fill it with data you need to see if your void function worked.
void
test_funtion(bool *answer)
{
answer = false;
// do stuff
if(error happens)
return;
answer = true;
return;
}
I don't see how you would use printf to let the program know.
Only way you would use printf for visual logging for yourself, but not the machine.

c, pointers, and argument list to printf. confused

Can someone explain why the value of the variable test isn't changed when I run the short code snippet below?
#include <stdio.h>
int f1(char * foo) {
*foo = 'a';
return 0;
}
void main(void) {
char test = 'n';
printf("f1(&test)=%d. test's new value? : %c", f1(&test), test);
}
I know I'm probably missing something really simple. I just don't understand why test isn't changed in f1() because I'm passing it's address in, right? Why does it matter that the actual function call happens in the list of arguments to printf() ?
If I take the call to f1() out of the printf argument list like so:
#include <stdio.h>
int f1(char * foo) {
*foo = 'a';
return 0;
}
void main(void) {
char test='n';
int i;
i = f1(&test);
printf("f1(&test)=%d. test's new value? : %c", i, test);
}
things work as expected.
thanks in advance.
The order in which the arguments to a function call are evaluated is unspecified. Put another way, you can't tell for sure when f1(&test) will be evaluated.
So in your example, perhaps f1(&test) is evaluated after test: slightly counter-intuitively, you don't get to see the side effects of that invocation. But if you print test again after the call, you will indeed see them.
Bottom line, just be careful with function that have side-effects and you should be set.
There is no set order in which function parameters are evaluated. You're banking on the idea that the arguments are evaluated left to right, which can't be assumed.
Just change where you make your function call
#include <stdio.h>
int f1 (char* foo) {
*foo='a';
return 0;
}
int main(void)
{
char test='n';
f1(&test);
printf("test=%c\n", test);
return 0;
}

Resources