Highly efficient string reversal code

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Richard

    Re: Highly efficient string reversal code

    Lew Pitcher <lpitcher@teksa vvy.comwrites:
    My contribution to the cause
    >
    char *reverse(char *str)
    {
    char *start, *end, temp;
    >
    for (end=str;*end;+ +end);
    --end; /* A */
    Did you not read the thread section where this is UDB in the case of
    zero length strings? A surprise to me too I must admit. And thats even
    before you use the illegal value in the comparison below.
    >
    for (start=str; start < end; ++start, --end) /* B */
    {
    temp = *start;
    *start = *end;
    *end = temp;
    }
    return str;
    }
    >
    NB: For the degenerate case of a zero-length string, the computation of the
    end character ( /* A */ ) produces a pointer that, *if dereferenced* would
    encounter UB because it points out-of-bounds to the intended array.
    *However*, the reversal loop ( /* B */ ) tests the value of this pointer
    (without dereferencing it), and will discontinue the loop immediately
    (again, without dereferencing the pointer).
    --

    Comment

    • brix99luftballons

      Re: Highly efficient string reversal code



      dominantubergee k@ymail.com ha scritto:
      Hello, I'm a highly experienced expert C programmer and I've written
      this code to reverse a string in place. I think you could all learn
      something from it!
      >
      int reverse(char* reverseme){
      int retval=-1;
      if(retval!=NULL ){
      int len=strlen(retv al){
      if(len>0){
      int half=len>>1;
      for(;retval<hal f;retval++){
      reverseme[retval]^=reverseme[len-(retval+1)];
      reverseme[len-(retval+1)]=reverseme[retval];
      reverseme[retval]^=reverseme[len-(retval+1)];
      }
      }
      }
      return retval;
      }
      >
      -Phil/CERisE
      >
      Just another little variation :

      void reverse(char* pStart)
      {
      char* pEnd;
      int len;

      if((NULL==pStar t) || (1 >= (len=(strlen(pS tart)))))
      return;

      pEnd= pStart+len;
      do{
      char t;

      pEnd--;
      t = *pStart;
      *pStart++ = *pEnd;
      *pEnd = t;
      }while(pStart < pEnd);
      }

      B.

      Comment

      • brix99luftballons

        Re: Highly efficient string reversal code

        Of course, that works, not like Your mental-disturbed code ;-)
        B.

        Comment

        • Lew Pitcher

          Re: Highly efficient string reversal code

          On September 24, 2008 09:49, in comp.lang.c, Ben Bacarisse
          (ben.usenet@bsb .me.uk) wrote:
          Lew Pitcher <lpitcher@teksa vvy.comwrites:
          >
          >My contribution to the cause
          >>
          > char *reverse(char *str)
          > {
          > char *start, *end, temp;
          >>
          > for (end=str;*end;+ +end);
          > --end; /* A */
          >>
          > for (start=str; start < end; ++start, --end) /* B */
          > {
          > temp = *start;
          > *start = *end;
          > *end = temp;
          > }
          > return str;
          > }
          >>
          >NB: For the degenerate case of a zero-length string, the computation of
          >the end character ( /* A */ ) produces a pointer that, *if dereferenced*
          >would encounter UB because it points out-of-bounds to the intended array.
          >
          You need to say why you dispute the claim that 6.5.6 paragraph 8 says
          the result is undefined behaviour:
          >
          "... If both the pointer operand and the result point to elements
          of the same array object, or one past the last element of the array
          object, the evaluation shall not produce an overflow; otherwise, the
          behavior is undefined."
          >
          >*However*, the reversal loop ( /* B */ ) tests the value of this pointer
          >(without dereferencing it), and will discontinue the loop immediately
          >(again, without dereferencing the pointer).
          >
          And then you'd have to say why the < operation is defined when most
          people read 6.5.8 paragraph 5 as saying that it is not.
          Oops. My bad. You are right, of course.

          So, I'll try again - how about this variation?

          char *reverse(char str[])
          {
          long int start, end;
          char temp;

          for (end=0;str[end];++end);
          --end;

          for (start=0; start < end; ++start, --end)
          {
          temp = str[start];
          str[start] = str[end];
          str[end] = temp;
          }
          return &str[0];
          }


          --
          Lew Pitcher

          Master Codewright & JOAT-in-training | Registered Linux User #112576
          http://pitcher.digitalfreehold.ca/ | GPG public key available by request
          ---------- Slackware - Because I know what I'm doing. ------


          Comment

          • Flash Gordon

            Re: Highly efficient string reversal code

            Lew Pitcher wrote, On 24/09/08 18:28:
            On September 24, 2008 09:49, in comp.lang.c, Ben Bacarisse
            (ben.usenet@bsb .me.uk) wrote:
            >
            >Lew Pitcher <lpitcher@teksa vvy.comwrites:
            >>
            >>My contribution to the cause
            >>>
            >> char *reverse(char *str)
            >> {
            >> char *start, *end, temp;
            >>>
            >> for (end=str;*end;+ +end);
            >> --end; /* A */
            >>>
            >> for (start=str; start < end; ++start, --end) /* B */
            >> {
            >> temp = *start;
            >> *start = *end;
            >> *end = temp;
            >> }
            >> return str;
            >> }
            >>>
            >>NB: For the degenerate case of a zero-length string, the computation of
            >>the end character ( /* A */ ) produces a pointer that, *if dereferenced*
            >>would encounter UB because it points out-of-bounds to the intended array.
            >You need to say why you dispute the claim that 6.5.6 paragraph 8 says
            >the result is undefined behaviour:
            >>
            > "... If both the pointer operand and the result point to elements
            > of the same array object, or one past the last element of the array
            > object, the evaluation shall not produce an overflow; otherwise, the
            > behavior is undefined."
            >>
            >>*However*, the reversal loop ( /* B */ ) tests the value of this pointer
            >>(without dereferencing it), and will discontinue the loop immediately
            >>(again, without dereferencing the pointer).
            >And then you'd have to say why the < operation is defined when most
            >people read 6.5.8 paragraph 5 as saying that it is not.
            >
            Oops. My bad. You are right, of course.
            >
            So, I'll try again - how about this variation?
            >
            char *reverse(char str[])
            {
            long int start, end;
            char temp;
            >
            for (end=0;str[end];++end);
            A problem is the string is longer than can be represented by a long int ;-)
            --end;
            >
            for (start=0; start < end; ++start, --end)
            {
            temp = str[start];
            str[start] = str[end];
            str[end] = temp;
            }
            return &str[0];
            Why not "return str"?
            }
            char *reverse(char *str)
            {
            if (str && *str) {
            char *end;
            char *start;
            /* subtract safe as already caught 0 length */
            for (start = str, end = strchr(str,0) - 1;
            end start;
            start++, end--) {
            char temp = *start;
            *start = *end;
            *end = temp;
            }
            }
            return str;
            }

            I think the only limits on this would be the limits on the C
            implementation and, of course, needing the pointer passed to be a valid
            pointer to the first[1] character modifiable string.

            [1] Well, the first character of the sub-string you want reversed, you
            could leave the start of a string unreversed by passing a pointer to a
            later character in the string.
            --
            Flash Gordon
            If spamming me sent it to smap@spam.cause way.com
            If emailing me use my reply-to address
            See the comp.lang.c Wiki hosted by me at http://clc-wiki.net/

            Comment

            • CBFalconer

              Re: Highly efficient string reversal code

              brix99luftballo ns wrote:
              >
              Of course, that works, not like Your mental-disturbed code ;-)
              What works? You failed to quote anything. Bad.

              See the following links:

              <http://www.catb.org/~esr/faqs/smart-questions.html>
              <http://www.caliburn.nl/topposting.html >
              <http://www.netmeister. org/news/learn2quote.htm l>
              <http://cfaj.freeshell. org/google/ (taming google)
              <http://members.fortune city.com/nnqweb/ (newusers)

              --
              [mail]: Chuck F (cbfalconer at maineline dot net)
              [page]: <http://cbfalconer.home .att.net>
              Try the download section.

              Comment

              • Malcolm McLean

                Re: Highly efficient string reversal code


                "Ben Bacarisse" <ben.usenet@bsb .me.ukwrote in message
                "Bartc" <bc@freeuk.comw rites:
                >
                >What's wrong about it? It works fine, provided str points to a valid
                >string.
                >
                There are two cases. If all of the values of size_t (the result of
                strlen) can be represented in an int (not likely, but possible) then
                the code works. If not, then strlen("") - 1 is a large positive
                number that is out of range for an int, and the conversion to int is
                implementation defined (which may include raising a signal).
                >
                See the evil?

                --
                Free games and programming goodies.


                Comment

                • Ben Bacarisse

                  Re: Highly efficient string reversal code

                  "Malcolm McLean" <regniztar@btin ternet.comwrite s:
                  "Ben Bacarisse" <ben.usenet@bsb .me.ukwrote in message
                  >"Bartc" <bc@freeuk.comw rites:
                  >>
                  >>What's wrong about it? It works fine, provided str points to a
                  >>valid string.
                  >>
                  >There are two cases. If all of the values of size_t (the result of
                  >strlen) can be represented in an int (not likely, but possible) then
                  >the code works. If not, then strlen("") - 1 is a large positive
                  >number that is out of range for an int, and the conversion to int is
                  >implementati on defined (which may include raising a signal).
                  >>
                  See the evil?
                  No, I see a problem if you subtract one from an unsigned number
                  that might be zero.

                  --
                  Ben.

                  Comment

                  • pete

                    Re: Highly efficient string reversal code

                    Flash Gordon wrote:
                    char *reverse(char *str)
                    {
                    if (str && *str) {
                    char *end;
                    char *start;
                    /* subtract safe as already caught 0 length */
                    for (start = str, end = strchr(str,0) - 1;
                    end start;
                    start++, end--) {
                    char temp = *start;
                    *start = *end;
                    *end = temp;
                    }
                    }
                    return str;
                    }
                    >
                    I think the only limits on this would be the limits on the C
                    implementation and, of course, needing the pointer passed to be a valid
                    pointer to the first[1] character modifiable string.
                    >
                    [1] Well, the first character of the sub-string you want reversed, you
                    could leave the start of a string unreversed by passing a pointer to a
                    later character in the string.
                    [1]Footnote not needed:
                    Every byte in a string,
                    is the first byte of some string.

                    My turn!

                    #include <string.h>

                    char *str_rev(char *s)
                    {
                    char *const p = s;
                    char *t;
                    char swap;

                    if (*s != '\0') {
                    t = s + strlen(s + 1);
                    while (t s) {
                    swap = *t;
                    *t-- = *s;
                    *s++ = swap;
                    }
                    }
                    return p;
                    }

                    --
                    pete

                    Comment

                    • Flash Gordon

                      Re: Highly efficient string reversal code

                      pete wrote, On 25/09/08 00:16:
                      Flash Gordon wrote:
                      <snip>
                      >[1] Well, the first character of the sub-string you want reversed, you
                      >could leave the start of a string unreversed by passing a pointer to a
                      >later character in the string.
                      >
                      [1]Footnote not needed:
                      Every byte in a string,
                      is the first byte of some string.
                      I new that, but without it someone would have complained that it was
                      valid to pass a pointer to part way through a string :-)
                      My turn!
                      >
                      #include <string.h>
                      >
                      char *str_rev(char *s)
                      {
                      char *const p = s;
                      char *t;
                      char swap;
                      >
                      if (*s != '\0') {
                      You've decided to leave s==NULL as undefined behaviour. This *is* a
                      perfectly valid design decision.
                      t = s + strlen(s + 1);
                      Clever, saved yourself a subtraction :-)
                      It will still fail with a really stupidly long string so long that
                      strlen fails ;-) Now I've just got to find a way to generate such a
                      string :-) Not a problem in practice, but one I deliberately sidestepped
                      by using strchr.

                      <snip>
                      --
                      Flash Gordon
                      If spamming me sent it to smap@spam.cause way.com
                      If emailing me use my reply-to address
                      See the comp.lang.c Wiki hosted by me at http://clc-wiki.net/

                      Comment

                      • CBFalconer

                        Re: Highly efficient string reversal code

                        Flash Gordon wrote:
                        pete wrote:
                        >
                        .... snip ...
                        >
                        >Every byte in a string, is the first byte of some string.
                        >
                        I new that, but without it someone would have complained that it
                        was valid to pass a pointer to part way through a string :-)
                        I doubt it. I suspect you will get more 'fix your k key' help.

                        --
                        [mail]: Chuck F (cbfalconer at maineline dot net)
                        [page]: <http://cbfalconer.home .att.net>
                        Try the download section.

                        Comment

                        • Flash Gordon

                          Re: Highly efficient string reversal code

                          CBFalconer wrote, On 25/09/08 16:10:
                          Flash Gordon wrote:
                          >pete wrote:
                          >>
                          ... snip ...
                          >>Every byte in a string, is the first byte of some string.
                          >I new that, but without it someone would have complained that it
                          >was valid to pass a pointer to part way through a string :-)
                          >
                          I doubt it.
                          I don't.
                          I suspect you will get more 'fix your k key' help.
                          Nothing wrong with it. There is also a perfectly good reason why my
                          spelling is sometimes less than perfect, and a spell checker enabled in
                          my Usenet client and all my email clients to minimise the errors.
                          --
                          Flash Gordon
                          If spamming me sent it to smap@spam.cause way.com
                          If emailing me use my reply-to address
                          See the comp.lang.c Wiki hosted by me at http://clc-wiki.net/

                          Comment

                          • Rosario

                            Re: Highly efficient string reversal code


                            "lovecreatesbea ...@gmail.com" <lovecreatesbea uty@gmail.comha scritto nel
                            messaggio
                            news:121ca8a7-6b38-4145-b5a4-15a9b87bc4cc@s2 0g2000prd.googl egroups.com...
                            On Sep 23, 9:28 am, "lovecreatesbea ...@gmail.com"
                            <lovecreatesbea ...@gmail.comwr ote:
                            On Sep 23, 7:22 am, pete <pfil...@mindsp ring.comwrote:
                            >
                            >
                            >
                            >
                            >
                            Richard wrote:
                            #include <string.h>
                            >
                            char * my_strrev(char *s){
                            char t;
                            char *e = s+strlen(s)-1;
                            while(e>s){
                            t = *s;
                            *s++ = *e;
                            *e-- = t;
                            }
                            }
                            unsigned my_strrev(char *s)
                            {unsigned h;
                            char *e, t;
                            if(s==0) return 0;
                            h=strlen(s);
                            if((int)h<=0) return 0;
                            e=s+h-1;
                            for( ;e>s ;--e,++s)
                            {t=*s; *s=*e; *e=t;}
                            return h;
                            }

                            not tested
                            don't know if "if((int)h< =0) return 0;" is right

                            I'm sure it breaks some sort of ISO magic, but it seems more concise
                            and
                            readable to me. No I didnt test it, but I guess the idea should be
                            self
                            evident.
                            >
                            It's undefined when attempting to reverse a zero length string.
                            >
                            How to reverse a zero length string for it has only a single NULL
                            terminating character : ) The reverse function quits if this is the
                            case.
                            My version

                            char *reverse(char *p)
                            {
                            char *p1, *p2, ch;

                            for (p1 = p; *(p1 + 1); p1++) ;
                            for (p2 = p; p2 < p1; p2++, p1--)
                            ch = *p2, *p2 = *p1, *p1 = ch;
                            return p;
                            }





                            Comment

                            • pete

                              Re: Highly efficient string reversal code

                              Rosario wrote:
                              "lovecreatesbea ...@gmail.com" <lovecreatesbea uty@gmail.comha scritto nel
                              messaggio
                              news:121ca8a7-6b38-4145-b5a4-15a9b87bc4cc@s2 0g2000prd.googl egroups.com...
                              On Sep 23, 9:28 am, "lovecreatesbea ...@gmail.com"
                              <lovecreatesbea ...@gmail.comwr ote:
                              >How to reverse a zero length string for it has only a single NULL
                              >terminating character : ) The reverse function quits if this is the
                              >case.
                              >
                              My version
                              >
                              char *reverse(char *p)
                              {
                              char *p1, *p2, ch;
                              >
                              for (p1 = p; *(p1 + 1); p1++) ;
                              *(p1 + 1) is undefined for a zero length string.

                              --
                              pete

                              Comment

                              • lovecreatesbeauty@gmail.com

                                Re: Highly efficient string reversal code

                                On Sep 26, 5:08 pm, pete <pfil...@mindsp ring.comwrote:
                                *(p1 + 1) is undefined for a zero length string.
                                It existed in my old reply. Been revised as follow:

                                char *reverse(char *p)
                                {
                                char *p1, *p2, ch;

                                p1 = p;
                                if (!*p) return p;
                                while (*p1) p1++;
                                p1--;
                                for (p2 = p; p2 < p1; p2++, p1--)
                                ch = *p2, *p2 = *p1, *p1 = ch;
                                return p;
                                }

                                Comment

                                Working...