Next different permutation in C
size and i in reverse look superficial. Consider
void reverse(int A[], int l, int r) {
    while (l &lt; r) {
        pswap(&amp;A[l++], &amp;A[r--]);
    }
}


The outer loop looks very strange. Its body is executed exactly once, when the longest decreasing interval is detected. Consider lifting the body out of the loop.
As a side point, I don't see the point of struct {int i; int j}. It is initialized to {r-1, r}, and at each iteration both members are decremented. z.i is always equal to  z.j - 1. Keeping just one int is enough. Consider
  int j = r; // j will point to the highest peak of the interval [i,r].
  // this loop will find the first increasing [i,j] from r to l.
  while (j &gt; l) {
      if (A[j-1] &lt; A[j]) {
          break;
      }
      --j;
  }

  if (j &gt; l) {
      int k = r;
      // find the first A[k] where A[k] &gt; A[j-1].
      while (!(A[j-1] &lt; A[k])) {
          --k;
      }
      pswap(&amp;A[j-1], &amp;A[k]);
      reverse(A, j, r);
      return true;
  }

  reverse(A, j, r);
  return false;

It already looks cleaner, but let's get going. An obvious next step is to get rid of the duplicate calls to reverse:
  if (j &gt; l) {
      ....
      pswap(....);
  }
  reverse (A, j, r);
  return j &gt; l;


No naked loops please. If you felt compelled to put comments like
      // find the maximal decreasing interval [j,r]
      // find the first A[k] where A[k] &gt; A[z.i].

you admit that you failed to express the intentions in the code. Consider refactoring these loops into functions. Consider
  int j = find_decreasing_interval(A, l, r);
  if (l &lt; j) {
      int k = lower_bound(A, j, r, A[j-1]);
      pswap(&amp;A[j-1], &amp;A[k]);
  }
  reverse((A, j, r);
  return j &gt; l;