Lothar: Frage zu strcmp

Hallo.

strcmp() vergleicht zwei Strings und gibt ein int zurück. Aber wie geht der Vergleich von Statten? werden die Strings in irgendwelche binären Werte umgewandelt und dann verglichen? Nur die Länge der Strings ist es sicherlich nicht.

Lothar

  1. Hi,

    strcmp() vergleicht zwei Strings und gibt ein int zurück. Aber wie geht der Vergleich von Statten?

    Zeichen für Zeichen, vom Beginn der Strings aus - wie denn sonst?

    MfG ChrisB

    --
    RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
    1. Zeichen für Zeichen, vom Beginn der Strings aus - wie denn sonst?

      Also ist die zurückgegebende Zahl der Wert von ...?

      1. Hi!

        Zeichen für Zeichen, vom Beginn der Strings aus - wie denn sonst?
        Also ist die zurückgegebende Zahl der Wert von ...?

        Der (im mathematischen Sinne) absolute Wert ist irrelevant. Es ist lediglich definiert, dass er kleiner, größer oder gleich 0 ist. Wenn du ihn dir konkret anschaust und er angenommenerweise 42 ist, sagt das dasselbe aus wie jeder andere positive Wert. Selbst wenn das zufälligerweise die Position der Abweichung ist, kannst du dich nicht darauf verlassen, dass das auf allen Systemen gleich ist. Viele Funktionen verwenden grundlegende Betriebssystemfunktionen oder andere von anderen entwickelte und auf konkrete Systeme spezialisierte Bibliotheken. Die Implementationen können unterschiedlich sein und auch unterschiedliche Werte liefern, solange sie in den dokumentierten Grenzen liegen.

        Lo!

        1. Interessant, danke.

          Also kann man auf den ersten Blick nicht herausbekommen wie die Ergebniszahl entsteht.

          1. Hallo,

            Also kann man auf den ersten Blick nicht herausbekommen wie die Ergebniszahl entsteht.

            man kann sich natürlich die tatsächliche Implementierung von strcmp() in den verschiedenen Runtime-Umgebungen anschauen; das ist ja das Schöne an Open Source.
            Ich habe bisher zwei prinzipiell verschiedene Methoden gesehen. Entweder die Funktionen geben explizit die Werte 0, +1 und -1 zurück, oder die Differenz der beiden Zeichen, an denen sich die Strings unterscheiden.

            Aber wie dedlfix schon sagte, ist dieser Wert eigentlich unerheblich, weil er nicht wirklich festgelegt ist und auf einem anderen System wieder anders sein kann (und darf).

            Ciao,
             Martin

            --
            Keine Sorge, wir finden für jede Lösung ein Problem.
            Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
            1. Danke.

              .

  2. Hallo,

    wenn ich die Quellen von PHP richtig lese, dann funktioniert die API Funktion strcmp() so:

      
    ZEND_API int zend_binary_strcmp(const char *s1, uint len1, const char *s2, uint len2) /* {{{ */  
    {  
    	int retval;  
      
    	retval = memcmp(s1, s2, MIN(len1, len2));  
    	if (!retval) {  
    		return (len1 - len2);  
    	} else {  
    		return retval;  
    	}  
    }  
    /* }}} */  
    
    

    Und in der man page von memcmp steht:
    "The memcmp() function returns zero if the two strings are identical, otherwise returns the difference between the first two differing bytes (treated as unsigned char values, so that \200' is greater than \0', for example).  Zero-length strings are always identical."

    Grüße

    1. wenn ich die Quellen von PHP richtig lese, dann funktioniert die API Funktion strcmp() so:

      ZEND_API int zend_binary_strcmp(const char *s1, uint len1, const char s2, uint len2) / {{{ */
      {
      int retval;

      retval = memcmp(s1, s2, MIN(len1, len2));
      if (!retval) {
      return (len1 - len2);
      } else {
      return retval;
      }
      }
      /* }}} */

        
      Ich würde sagen, das kommt aus zend\_builtin\_functions.c:  
        
      ~~~c
      /* {{{ proto int strcmp(string str1, string str2)  
         Binary safe string comparison */  
      ZEND_FUNCTION(strcmp)  
      {  
      	zval **s1, **s2;  
      	  
      	if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &s1, &s2) == FAILURE) {  
      		ZEND_WRONG_PARAM_COUNT();  
      	}  
      	convert_to_string_ex(s1);  
      	convert_to_string_ex(s2);  
      	RETURN_LONG(zend_binary_zval_strcmp(*s1, *s2));  
      }  
      /* }}} */
      

      Afaik steht alles was PHP_FUNCTION bzw. ZEND_FUNCTION heisst für PHP (sprich für den Benutzer) als Funktion zur Verfügung.

      http://php.net/manual/en/internals2.ze1.zendapi.php
      http://www.php.net/manual/en/internals2.funcs.php

      1. Hallo,

        Ich würde sagen, das kommt aus zend_builtin_functions.c:

        ja, richtig. Aber du schaust in eine andere PHP Version als ich? Bei mir steht dort nämlich:

          
        ZEND_FUNCTION(strcmp)  
        {  
        	char *s1, *s2;  
        	int s1_len, s2_len;  
          
        	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &s1, &s1_len, &s2, &s2_len) == FAILURE) {  
        		return;  
        	}  
          
        	RETURN_LONG(zend_binary_strcmp(s1, s1_len, s2, s2_len));  
        }  
        
        

        Meine Quelle war diese:
        http://svn.php.net/repository/php/php-src/branches/PHP_5_3/Zend/zend_builtin_functions.c

        Afaik steht alles was PHP_FUNCTION bzw. ZEND_FUNCTION heisst für PHP (sprich für den Benutzer) als Funktion zur Verfügung.

        Ja, sehe ich auch so.

        Grüße

        1. Ich würde sagen, das kommt aus zend_builtin_functions.c:
          ja, richtig. Aber du schaust in eine andere PHP Version als ich?

          Offensichtlich, ja ;)

          Meine Quelle war diese:
          http://svn.php.net/repository/php/php-src/branches/PHP_5_3/Zend/zend_builtin_functions.c

          Ich hatte lokal grade nur eine 5.2.17 zur Verfügung :)