[C] functie aanroepen met pointer & uitvoer pointer

Pagina: 1
Acties:
  • 233 views sinds 30-01-2008
  • Reageer

  • Xorgye
  • Registratie: Maart 2005
  • Laatst online: 05-10-2024
Ik programmeer al tijden, maar wil toch maar eens wat 'cleaner' gaan programmeren.
Dit houd in dat ik een functie aan wil roepen en van de functie een waarde terug wil krijgen zonder dat de functie in een globale variabele zijn antwoord stopt.

Aangezien ik met C werk in de Dev-C++ compiler en dus ook wat C++ mag gebruiken, dacht ik dat het gebruik van een pointer wel handig zou zijn. Je stopt er een pointer in en die krijg je terug, nu naar de gemodificeerde informatie.

Nu de vraag: ik wilde graag dat een tekenreeks bewerkt zou worden, en ik aan de functie niet een pointer maar een characterreeks omgezet naar pointer geef.

Ik ben absoluut niet bekend met hoe je pointers moet gebruiken en hoe je een char naar een pointer mag overzetten. Zelf dacht ik hier aan, maar dat werkt dus niet:
C:
1
2
3
4
5
6
7
8
9
10
11
12
int main()
{
     char tekenreeks[5]; 
     pointernaarreeks = lowercase(&tekenreeks);
}

long lowercase(long tekenreeks)
{
     long pointernaarresultaat;
     //bewerk de tekenreeks
     return pointernaarresultaat;
}


Het maakt trouwens niet uit dat ik een pointer terug krijg (hoewel char mischien ook handig is, maar dit heb ik ook voor andere dingen nodig)

  • twanvl
  • Registratie: Februari 2005
  • Laatst online: 10-11-2025
Een long is geen pointer. In C hebben pointers een type dat aangeeft waarnaar gewezen wordt. In jouw geval is dat een char** (pointer-naar pointer-naar/array-van char). Die tweede laag heb je in dit voorbeeld zelfs niet echt nodig, omdat je niet de plaats in het geheugen van de string (de char*) hoeft te veranderen. Een tekenreeks is trouwens geen 'char', maar 'char[]' of 'char*'.
Jou voorbeeld kan je op twee manieren aanpakken:
  1. Je bewerkt de inkommende tekenreeks zodanig dat ie lowercase wordt.
  2. Je maakt een kopie van de tekenreeks, en maakt die kopie lowercase.
De eerste oplossing heeft hier de voorkeur, omdat je in het tweede geval heel erg op moet passen wij de nieuwe tekenreeks alloceert.

  • joca
  • Registratie: Oktober 2000
  • Laatst online: 12-07-2025
Als je een functie met een pointer wilt aanroepen moet je wel zorgen dat je functie weet dat hij een pointer mee krijgt.

Je hoeft overigens geen pointer terug te geven tenzij je de uitkomst in een ander array zet. Met een pointer geef je het adres van je functie mee en kan je de data in je tekenreeks array aanpassen.

Wil je wel een pointer teruggegeven zie dan voorbeel 2.


C:
1
2
3
4
5
6
7
8
9
10
11
12
13
/*prototyping*/
void lowercase(char * )

int main()
{
     char tekenreeks[5]; 
     lowercase(&tekenreeks);
}

void lowercase(char * tekenreeks)
{
     //bewerk de tekenreeks   
}



C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/*prototyping*/
unsigned char * lowercase(char * tekenreeks)

int main()
{
     char tekenreeks[5]; 
     unsigned char * pointernaarreeks;
     pointernaarreeks = lowercase(&tekenreeks);
}

unsigned char * lowercase(char * tekenreeks)
{
     char result[5];
     //bewerk de tekenreeks
     return &result;
}

Verwijderd

&var is het adres van een variabele, aangezien C maar twee variabelen kent (pointers en getallen) is een array een pointer naar een aantal gelijke elementen achter elkaar.
char string[5];
betekent dus dat string al een pointer is (namelijk een pointer naar het eerste element uit de array van chars).
Speciaal voor pointers heeft C het sterretje *. Als je een pointer naar een char element (of een reeks van die dingen) wilt maken gebruik je daarvoor char*.
char* pointernaarreeks;
maakt dus een pointer die verwijst naar een char element.
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
int main() 
{ 
     char tekenreeks[5];
     char* pointernaarreeks;
     pointernaarreeks = lowercase(tekenreeks);
} 

char* lowercase(long tekenreeks) 
{ 
     char* pointernaarresultaat; 
     //bewerk de tekenreeks 
     return pointernaarresultaat; 
}

Als je alleen de individuele letters veranderd zal je dus de string als geheel niet veranderen, dat betekent dat pointernaarreeks == pointernaarresultaat == tekenreeks.
In dit geval hoef je dus zelfs niets terug te geven, aangezien je functie direct de gegevens uit je main() aanpast!

  • Xorgye
  • Registratie: Maart 2005
  • Laatst online: 05-10-2024
Sorry, dat ik het prototyping was vergeten in te voegen ;)
De compiler wijst me er elke keer op... en vergeet 't nog steeds...

Maar ik heb nu voldoende informatie.
Ik hoeft inderdaad geen pointer terug te geven omdat de data die in de lokale reeks staat al verandert is na de aanroep van de functie. Handig, zo'n pointer :*)

  • Xorgye
  • Registratie: Maart 2005
  • Laatst online: 05-10-2024
Het resultaat is geworden:
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <stdio.h>
#include <string.h>

#define LOWERCASE                   1

bool bewerkreeks(int opdracht, char * tekenreeks);


int main()
{
    char naam[45];
    strcpy(naam, "XorgYe1234");
     
    printf(" naam [%s] word ", naam);
    
    bewerkreeks(LOWERCASE, naam);
    
    printf("naam [%s]\n", naam);

    
    char str[80];
    scanf("%s",str);
}


bool bewerkreeks(int opdracht, char * tekenreeks)
{
     switch(opdracht)
     {
          case LOWERCASE:
          {
               int x = 0;
               while(tekenreeks[x] != 0)
               {
                    if(tekenreeks[x] >= 'A' && tekenreeks[x] <= 'Z')
                    {
                         tekenreeks[x] = tekenreeks[x] - ('A' - 'a');
                    }
                    x++;
               }
               return true;
          } break;
          default: break;
     }
     return false;
}


*Deze post is gemodified... omdat ik hiervoor een super domme opmerking maakte bij de code*

[ Voor 59% gewijzigd door Xorgye op 14-05-2005 16:27 . Reden: Mensen... ik zit er niet met me hoofd bij. Ik had deze post eerder gepost met de gedachte dat hij niet werkte... na de 2e keer compilen bleek het tegendeel... ]


  • Ivo
  • Registratie: Juni 2001
  • Laatst online: 14-01-2025

Ivo

//gaat het werken als ik hier als 2e parameter gewoon 'naam' opgeef? Moet
//ik die niet omzetten naar pointer?
Dat gaat goed zo. Naam van array is hetzelfde als pointer naar eerste element van dat array. Dus:

array = &array[0]

[ Voor 5% gewijzigd door Ivo op 14-05-2005 16:24 ]


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
Werkt niet voor non-ASCII. Probeer tolower( ) eens.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • MrBucket
  • Registratie: Juli 2003
  • Laatst online: 29-10-2022
Joca schreef op zaterdag 14 mei 2005 @ 15:54:
C:
1
2
3
4
5
6
unsigned char * lowercase(char * tekenreeks)
{
     char result[5];
     //bewerk de tekenreeks
     return &result;
}
Dit wil je niet doen (alhoewel het in veel gevallen wel zal lijken te werken - niet in alle gevallen).
Je retourneert hier nl. het adres van een lokale variabele 'result'. Officieel bestaat, na beeindiging van de functie lowercase(), deze variabele niet meer en dus verwijst de geretourneerde pointer naar een stuk vrijgegeven geheugen (!!!).
Bovendien zou je "return result" (zonder '&') moeten schrijven. De expressie 'result' is nl. een pointer naar het 0e element van de char array.

  • joca
  • Registratie: Oktober 2000
  • Laatst online: 12-07-2025
Ja klopt idd, even niet over nagedacht. Hetzelfde geldt eigenlijk ook voor z'n huidige oplossing met de aanroep vanuit main, daar wordt ook een lokale variabele gebruikt.

Voor de return was idd &result[0] of result de oplossing geweest.
Pagina: 1