Helmut Leitner / Mem Find
StartSeite | HelmutLeitner/ | Neues | TestSeite | ForumSeite | Teilnehmer | Kategorien | Index | Hilfe | Einstellungen | Ändern
Ein kleiner Ausschnitt aus dem Mem-Modul (SpracheCee), um eine Frage in dclc beantworten zu können... (/VerwendeteTypKurzbezeichnungen)
| /*=*//**MF1**/
CH *MemFindMem(CH *p,OS len,CH *ss,OS sslen)
/**MFK Sucht in einem Speicherbereich nach einer Bytesequenz.**/
{
CH *sp;
CH *ep;
OS i;
if(sslen>len) {
return NULL;
}
ep = p + len - sslen;
sp = p;
while(sp<=ep) {
for(i=0; i<sslen; i++) {
if(sp[i]!=ss[i]) {
break;
}
}
if(i==sslen) {
return sp;
}
sp++;
}
return NULL;
}
/*=*//**MF1**/
CH *MemFindStr(CH *p,OS len,CH *ss)
/**MFK Sucht in einem Speicherbereich nach einem String.**/
{
return MemFindMem(p,len,ss,strlen(ss));
} |
|
|
Wie immer, interessiert mich die konkrete Implementierung relativ wenig (ausser ihrer Einfachheit und Lesbarkeit), die Sprache und die Logik der Interfaces jedoch sehr. Siehe WardsWiki:LanguageOrientedProgramming.
Durch Umformulierung kann man bei MemFindMem() auf folgende Variante kommen (Vorsicht, ungetestet), die (falls sie funktioniert ;-) nicht weniger einfach und lesbar als das Original sein dürfte. -- VolkerGlave
| /* Sucht in einem Speicherbereich nach einer Bytesequenz. */
CH *MemFindMem(CH *p, OS len, CH *ss, OS sslen)
{
if (sslen <= len)
{
for (CH *ep = p + len - sslen; p <= ep; ++p)
{
for (OS i = 0; /*loop*/; ++i)
{
if (i >= sslen)
{
return p;
}
else if (p[i] != ss[i])
{
break;
}
}
}
}
return NULL;
} |
|
|
Na ja, sie ist auf jeden Fall kürzer. Es gibt für mich viele persönliche Gründe, das nicht so zu schreiben - aber das wird dich ja nicht überraschen. Einige Kommentare:
- Gut finde ich das defensive i>=sslen, das ich meist auch verwende (ich weiß nicht, warum oben nicht).
- Die Linksverschiebung der Pointer-Sternchen (CH* p) statt (CH *p) ist IMO nicht gut. Sie weckt falsche Assoziationen und ist auch nicht üblich.
- Die Definition der Schleifenvariablen in den Schleifen ist nicht sehr portabel (ist das C99?). Ausserdem fehlt nun der natürliche Platz, den Variablen einen Kommentar beizufügen.
- das Weglassen der Klammern ist IMHO nicht wartungsfreundlich. Ebenso, wie das Mitverwenden des Pointers p (das hat auch Nachteile im Debugger, weil der Parameter nicht sichtbar bleibt.
- das erste "if" spart auch Zeilen, erhöht aber die Verschachtelungstiefe. In dem Fall spielt es keine Rolle, als Prinzip (wird oft als Prinzip verwendet) ist diese Vorgangsweise aber IMO nachteilig und macht einen Code unübersichtlicher.
- Alles natürlich IMHO. -- hl
Zu Punkt 2: Nach etwas Recherche (Beispiel) muss ich feststellen, dass ich mich da tatsächlich unüblicher Schreibweise bedient habe. Ich hab's jetzt gerade gezogen. Interessanterweise hab' ich vor vielen Jahren das auch immer so gemacht, bin dann aber zur andere Schreibweise übergegangen, wahrscheinlich beim Wechsel zu C++, wo denke ich diese andere Schreibweise üblich ist. Irgendwie blöd, dass da keine Gleichförmigkeit besteht.
Zu Punkt 3a: Klammern sind jetzt drin, sogar gerne, wenn auch weniger aus Wartungsfreundlichkeit, sondern weil ich per se der Fraktion angehöre, die eine vertikal gelockerte Schreibweise für leichter lesbar hält (auch öffnende Klammern landen auf je einer eigenen Zeile). Durch berufliche Zwänge ist das leider etwas verschütt gegangen.
Zu Punkt ...: ... InArbeit ... -- vgl
| byte *MemFindMem(byte *p, int len, byte *ss, int sslen)
{
byte *p1, *ss0;
for (ss0=ss; 1; sslen+=ss-ss0,ss=ss0,len+=p-p1,p=p1+1)
{
while (--len>=0&&*ss!=*p) ++p;
if (p1=p, len<0) break;
while (--sslen>0&&--len>=0&&*++ss==*++p);
if (sslen<=0||len<0) return p1;
}
return 0;
}
// 1. Entwurf
// Liefert auch !=NULL bei Teilpassung ganz am Ende von p+len,
// falls Suchmuster Blöcke überlappen. |
|
|
Zeitbedarf (von oben nach unten):
156 (hl)
195 (vgl)
100 (hs)
gcc 2.92.3, -O3 +
--HelmutSchellong aka (in his own words) "Der Produktamlebenerhalter"
Jawohl! Aber man muß wissen, daß ich dort zuvor behauptend diverse x-mal als arbeitsloser, kiffender Möchtegernprogrammierer der miesesten und unfähigsten Kategorie beschimpft wurde.
/Beispiel:
KategorieC KategorieCee KategorieProgrammierBeispiele KategorieSchellong
StartSeite | HelmutLeitner/ | Neues | TestSeite | ForumSeite | Teilnehmer | Kategorien | Index | Hilfe | Einstellungen | Ändern
Text dieser Seite ändern (zuletzt geändert: 29. November 2007 8:37 (diff))