Pekare och array

Download Report

Transcript Pekare och array

Minnen, variabler,
att lagra i primärminnet
forts.
Anders Sjögren
Fördefinierade minnesvariabeltyper
int main() {
char
int
float
double
”
”
tecken;
heltal;
flyttal;
dubbeltFlyttal;
Anders Sjögren
Array ( vektor, matris )
ett exempel som illustrerar behovet
Antag att man vill mäta
temperaturen flera gånger
och spara värdena för
statistisk behandling .
Hur gör man ett program
som läser in flera
mätvärden?
Anders Sjögren
#include
<stdio.h>
Varför array ?
int main(void)
{
int
temp1, temp2, temp3, temp4, temp5;
int
temp6, temp7, temp8, temp9, temp10;
printf("Ge
printf("Ge
printf("Ge
printf("Ge
printf("Ge
printf("Ge
printf("Ge
printf("Ge
printf("Ge
printf("Ge
temperatur
temperatur
temperatur
temperatur
temperatur
temperatur
temperatur
temperatur
temperatur
temperatur
-->
-->
-->
-->
-->
-->
-->
-->
-->
-->
");
");
");
");
");
");
");
");
");
");
scanf("%d",&temp1);
scanf("%d",&temp2);
scanf("%d",&temp3);
scanf("%d",&temp4);
scanf("%d",&temp5);
scanf("%d",&temp6);
scanf("%d",&temp7);
scanf("%d",&temp8);
scanf("%d",&temp9);
scanf("%d",&temp10);
printf("\ntemp = %d", temp1);
return 0;
}
Klumpigt !
Anders Sjögren
Varför array ?
#include <stdio.h>
int main(void)
{
int
temp[10];
int
i;
detta skapar 10 st minnen
i primärminnet ( på
stacken i detta fall) som
vardera kan lagra en int.
En array ( vektor ) om 10
element har sett dagens
ljus
for (i=0 ; i<10 ; i++){
printf("Ge temperatur %d --> ",i); scanf("%d",&temp[i]);
}
for (i=0 ; i<10 ; i++)
printf("\ntemp %d = %d",i, temp[i]);
return 0;
}
Bra, hyfsat!
Anders Sjögren
Varför array?
Anders Sjögren
Varför array ?
#include <stdio.h>
int main(void)
{
int
temp[10];
int
i;
detta skapar 10 st minnen
i primärminnet ( på
stacken i detta fall) som
vardera kan lagra en int.
En array ( vektor ) om 10
element har sett dagens
ljus
for (i=0 ; i<10 ; i++){
printf("Ge temperatur %d --> ",i); scanf("%d",&temp[i]);
}
for (i=0 ; i<10 ; i++)
printf("\ntemp %d = %d",i, temp[i]);
return 0;
}
Bra, hyfsat!
Anders Sjögren
Bytes
symboldefinitioner
Maskinkod
programmet
Ett minnesutrymme, variabel, i primärminnet
Heap
Ett minnesutrymme, variabel, i primärminnet som
kan lagra en adress dvs en pekare. Pekaren kan
tilldelas ett nytt värde.
Stack
En adress, pekare vars värde är konstant.
Anders Sjögren
Bytes
Vad är en array ?
int
int
Maskinkod
programmet
temp
temp[0]
temp[1]
int main(void)
{
int
temp[10];
int
i;
Heap
temp[6]
temp[9]
OBS! Första
indexnummer
är 0 !!
Stack
*temp == temp[0]
Anders Sjögren
Vad är en array ?
• stega på index
for (i=0 ; i<10 ; i++)
printf("\ntemp %d = %d",i, temp[i]);
int
int
temp
temp[0]
temp[1]
temp[6]
temp[9]
Anders Sjögren
Vad är en array ?
• stega på index
for (i=0 ; i<10 ; i++)
printf("\ntemp %d = %d",i, temp[i]);
int
int
• pekarstegning
effektivare = snabbare
int*
temp
temp[0]
temp[1]
heltalsPekare;
temp[6]
heltalsPekare = temp ;
for (i=0 ; i<10 ; i++)
printf("\ntemp %d =
%d",i,*heltalsPekare++);
temp[9]
heltalspekare
Anders Sjögren
Vad är en array ?
• stega på index
• pekarstegning
effektivare = snabbare
int*
ofta är kompilatorerna standardmässigt
for inställda
(i=0 ;
; i++)
på i<10
att optimera
maskinkoden så
printf("\ntemp
%d till
= %d",i,
temp[i]);
indexstegning översätts
pekarstegning vid kompilering. Vill man ändra
på detta måste int
man ändra
int
kompilatordirektiven. Man kan studera
detta genom att kompilera mot
temp[0]
assemblerkod. temp[1]
temp
heltalsPekare;
temp[6]
heltalsPekare = temp ;
for (i=0 ; i<10 ; i++)
printf("\ntemp %d =
%d",i,*heltalsPekare++);
temp[9]
heltalspekare
Anders Sjögren
Längden på en array ?
int main(void)
{
int
temp[10];
int
i;
• tänk om arrayen inte räcker till !
Anders Sjögren
Längden på en array ?
• om man inte vet längden på arrayen i förväg så
kan man allokera minne dynamiskt under
int main(void)
exekvering
{
int
int
*tempPekare;
n,i,j;
int
int
temp[10];
i;
printf("Ange antal temperaturer --> "); scanf("%d",&n);
tempPekare = (int *) calloc(n,sizeof(int));
for (i=0 ; i<n ; i++){
printf("Ge temperatur %d --> ",i); scanf("%d",tempPekare+i);
}
Anders Sjögren
Syntax
calloc(), ur manualen
#include <stdlib.h>
void *calloc(size_t nitems, size_t size);
Description
Allocates main memory. calloc provides access to the C memory heap. The heap is available
for dynamic allocation of variable-sized blocks of memory. Many data structures, such as trees
and lists, naturally employ heap memory allocation.
All the space between the end of the data segment and the top of the program stack is available
for use in the small data models (small and medium),except for a small margin immediately
before the top of the stack. This margin allows room for the application to grow on the stack,
and provides a small amount of room needed by the operating system.
In the large data models (compact, large, and huge), all space beyond the program stack to the
end of physical memory is available for the heap.
calloc allocates a block of size nitems * size. The block is cleared to 0. If you want to allocate
a block larger than 64K, you must use farcalloc.
Return Value
calloc returns a pointer to the newly allocated block. If not enough space exists for the new
block or if nitems or size is 0, calloc returns NULL.
Anders Sjögren
Vad är skillnaden på de två ?
Bytes
int
Maskinkod
programmet
Heap
Stack
*tempPekare;
tempPekare = (int *) calloc(n,sizeof(int));
10 st
int
10 st
int
<------ måste avallokeras av
programmeraren !
int
main()
temp[10];
<------ avallokeras
automatiskt !
Anders Sjögren
Vad är skillnaden på de två ?
Bytes
int
*tempPekare;
Det är jag som programmerare
som ansvarar för att minne,
tempPekare
allokerat dynamiskt
på heapen, =
tas (int *) calloc(n,sizeof(int));
Maskinkod
bort. Annars finns de kvar så
programmet
länge programmet finns kvar.
Heap
Stack
10 st
int
10 st
int
<------ måste avallokeras!
int
main()
temp[10];
Anders Sjögren
Vad är skillnaden på de två ?
Bytes
int
Maskinkod
programmet
Heap
Stack
*tempPekare;
tempPekare = (int *) calloc(n,sizeof(int));
10 st
int
10 st
int
Jag måste också akta mig noga så jag inte
skriver över adressen som nu finns lagrad i
tempPekare. Om jag gör det så får jag ett
borttappat ( dinglande) minne som inte kan
användas eller avallokeras.
<------ måste avallokeras!
int
main()
temp[10];
Anders Sjögren
#include
#include
<stdio.h>
<stdlib.h>
Hela programmet
int main(void) {
int *tempPekare;
int n,i,j;
printf("Ange antal temperaturer --> "); scanf("%d",&n);
tempPekare = (int *) calloc(n,sizeof(int));
for (i=0 ; i<n ; i++){
printf("Ge temperatur %d --> ",i); scanf("%d",tempPekare+i);
}
for (i=0 ; i<n ; i++)
printf("\ntemp %d = %d",i, tempPekare[i]);
free(tempPekare) ;
return 0;
}
Anders Sjögren
#include
#include
<stdio.h>
<stdlib.h>
Hela programmet
int main(void) {
int *tempPekare;
int n,i,j;
printf("Ange antal temperaturer --> "); scanf("%d",&n);
tempPekare = (int *) calloc(n,sizeof(int));
for (i=0 ; i<n ; i++){
printf("Ge temperatur %d --> ",i); scanf("%d",tempPekare+i);
}
för att en pekare ska kunna användas
for (i=0 ; i<n ; i++)
den peka på en känd datatyp.
printf("\ntemp %d = %d",i,måste
tempPekare[i]);
calloc() returnerar en pekare till typen
void (ingenting) så måste pekaren
free(tempPekare) ;
”castas” till att peka på någon
känd typ.
return 0;
}
Anders Sjögren
Det finns yttterligare en
#include <stdlib.h> or #include<alloc.h>
funktion
void *malloc(size_t size);
för dynamisk minnesallokering
Description
malloc()
Allocates main memory.
Syntax
malloc allocates a block of size bytes from the memory heap. It allows a program to allocate
memory explicitly as it's needed, and in the exact amounts needed. The heap is used for
dynamic allocation of variable-sized blocks of memory. Many data structures, for example,
trees and lists, naturally employ heap memory allocation.
All the space between the end of the data segment and the top of the program stack is available
for use in the small data models, except for a small margin immediately before the top of the
stack. This margin is intended to allow the application some room to make the stack larger, in
addition to a small amount needed by DOS.
In the large data models, all the space beyond the program stack to the end of available emory
is available for the heap.
Return Value
On success, malloc returns a pointer to the newly allocated block of memory. If not enough
space exists
for the new block, it returns NULL. The contents of the block are left unchanged. If the
argument size ==
0, malloc returns NULL.
Anders Sjögren
Strängar
att hantera text
• strängar är en array av tecken
• sista tecknet skall
vara ’\0’, ASCII nr 0
strang1
int main() {
char
strang1[10]={'H','e','j','\0'};
char
H
strang1[0]
e
j
\0
?
?
?
?
?
?
strang1[9]
Anders Sjögren
Kopiera arrayer - strängar
int main()
char
char
char*
{
strang1[10]={'H','e','j','\0'};
strang2[10];
strangPekare;
char
char
strang1
strang2
H
strang2[0]
?
?
?
?
?
?
?
?
?
strang1[0]
e
j
\0
?
?
?
?
?
?
char
?
strangPekare
?
Anders Sjögren
Kopiera arrayer - strängar
int main() {
strang2 = strang1 ;
char
strangPekare = strang1;
tilldelar bara
adressen till
element 0.
strang2
char
strang1
H
strang2[0]
?
?
?
?
strangPekare
?
?
?
char
?
?
?
strang1[0]
e
j
\0
?
?
?
?
?
?
?
Anders Sjögren
Kopiera arrayer - strängar
#include <string.h>;
int main() {
strang2 = strang1 ;
strcpy( strang2,strang1);
detta löser
problemet!
strang2
char
char
strang1
H
strang2[0]
e
j
\0
?
?
?
?
?
H
strang1[0]
e
j
\0
?
?
?
?
?
?
?
Anders Sjögren
Matriser
• flerdimensionella arrayer
int
main() {
int
matris[10][3];
matris[8][2] = 5;
5
Anders Sjögren
Sortera element i en array
funktionspekare införs
antag att man vill sortera bokstäverna
i en sträng
char
string
H
string[0]
e
j
\0
?
?
?
?
?
?
Anders Sjögren
Sortera element i en array
• funktion för detta finns redan
Anders Sjögren
Sortera element i en array
• funktion för detta finns redan
Anders Sjögren
Sortera element i en array
• funktion för detta finns redan
qsort()
i stdlib.h
Anders Sjögren
Sortera element i en array
qsort()
i stdlib.h
Wikipedia Quicksort
Anders Sjögren
Sortera element i en array
• funktion för detta finns redan
och prototypen ser ut på följande sätt
void qsort(void *base, size_t nelem, size_t width,
int (*fcmp)(const void *, const void *));
• void *base är en pekare till ”vad som helst” men som
kan konverteras (cast) att peka på någon känd typ.
Missar man att göra en cast till känd typ så sker en
implicit konvertering. I detta fall ska det vara en
pekare till 1:a elementet i arrayen som skall sorteras.
Anders Sjögren
Sortera element i en array
• funktion för detta finns redan
och prototypen ser ut på följande sätt
void qsort(void *base, size_t nelem, size_t width,
int (*fcmp)(const void *, const void *));
• size_t är ett makro som i ANSI-standard
anger typen på returvärdet för funktionen
sizeof(). Här ska man ange hur många
element det finns i arrayen som skall
sorteras.
Anders Sjögren
Sortera element i en array
• funktion för detta finns redan
och prototypen ser ut på följande sätt
void qsort(void *base, size_t nelem, size_t width,
int (*fcmp)(const void *, const void *));
• size_t är ett makro som i ANSI-standard
anger typen på returvärdet för funktionen
sizeof(). Här ska man ange hur stort varje ( i
bytes) element i arrayen som skall sorteras
är.
Anders Sjögren
Sortera element i en array
funktionspekare
• funktion för detta finns redan
och prototypen ser ut på följande sätt
void qsort(void *base, size_t nelem, size_t width,
int (*fcmp)(const void *, const void *));
• pekare till en funktion (funktionspekare)
vars argument är två void-pekare och som
returnerar en int. Denna funktion specifierar
hur det skall sorteras. Funktionen döper
man och skriver själv.
Anders Sjögren
Funktionspekare
• på samma sätt som string är en adress till första
elementet i arrayen
char
string[10];
• så är ett funktionsnamn utan parenteser
Sorteringsordning adressen till funktionen
int
Sorteringsordning( void * a , void * b );
Anders Sjögren
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int
Sortering implementerat
Sorteringsordning( const void* a, const void* b);
int main ( void )
{
char
string[10]={ '\0' } ;
int
i ;
printf("Skriv text max 9 tecken: --> ");
scanf("%s", string);
qsort( (void*) string , strlen( string ) , sizeof( char ) ,
Sorteringsordning );
for ( i=0; string[i]!='\0' ; i++)
printf("%c", string[i]);
return 0 ;
}
Anders Sjögren
Funktionen
Sorteringsordning()
• sorterar på tecknens ASCII-kod
int
Sorteringsordning( const void* a, const void* b){
if ( *((char *)a) < *((char *)b)
)
else if ( *((char *)a) > *((char *)b) )
else
return -1 ;
return 1 ;
return 0 ;
}
Anders Sjögren
Funktionen
Sorteringsordning()
• sorterar på summan av tecknens ASCIIkodbitmönster
int
Sorteringsordning( const void* a, const void* b){
int summaA, summaB;
summaA = BinSumma(*((char *)a));
summaB = BinSumma(*((char *)b)) ;
if
( summaA < summaB)
return -1 ;
else if ( summaA > summaB)
return 1 ;
else if ( *((char *)a) < *((char *)b)
)
else if ( *((char *)a) > *((char *)b)
else
)
return -1 ;
return 1 ;
return 0 ;
}
Anders Sjögren
Funktionen BinSumma()
• sorterar på summan av tecknens ASCIIkodbitmönster
int BinSumma( char tal ) {
int
static int
rest ;
langd = 0;
Blev samma!
langd++ ;
rest = tal % 2 ;
(men inte alltid – å ä ö …)
tal /= 2 ;
if (tal==0 || langd==8) { /* summerar över 1 byte */
langd = 0 ;
return rest ;
}
else
return rest + BinSumma( tal );
}
Anders Sjögren
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int Sorteringsordning( const void* a, const void* b);
int BinSumma( char tal );
int main ( void )
{
char
int
Hela programmet,
översikt
string[10]={ '\0' } ;
i
;
main()
printf("Skriv text max 9 tecken: --> ");
scanf("%s", string);
qsort( (void*) string , strlen( string ) , sizeof( char ) , Sorteringsordning );
for ( i=0; string[i]!='\0' ; i++)
printf("%c", string[i]);
return 0 ;
}
int
Sorteringsordning( const void* a, const void* b){
int summaA, summaB;
summaA = BinSumma(*((char *)a));
summaB = BinSumma(*((char *)b)) ;
if
( summaA < summaB) return -1 ;
else if ( summaA > summaB) return 1 ;
else if ( *((char *)a) < *((char *)b) ) return -1 ;
else if ( *((char *)a) > *((char *)b)
else return 0 ;
return 0 ;
Sorteringordning()
) return 1 ;
}
int BinSumma( char tal ) {
int
static int
rest ;
langd = 0;
langd++ ;
rest = tal % 2 ;
tal /= 2 ;
if (tal==0 || langd==8) { /* summerar över 1 byte */
langd = 0 ;
return rest ;
}
else return rest + BinSumma( tal );
BinSumma()
Anders Sjögren
Sortera strängarna
char list[5][4] = { "cat", "car", "cab", "cap", "can" };
c
c
a
c
a
t
a
r
\0
c
c
a
b
\0
a
p
\0
n
\0
\0
Anders Sjögren
Sortera strängar
/* qsort example */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
• i sort_function() kan man
använda strcmp()
int sort_function( const void *a, const void *b);
char list[5][4] = { "cat", "car", "cab", "cap", "can" };
int main(void)
{
int x;
qsort((void *)list, 5, sizeof(list[0]), sort_function);
for (x = 0; x < 5; x++)
printf("%s\n", list[x]);
return 0;
}
int sort_function( const void *a, const void *b)
{
return( strcmp((char *)a,(char *)b) );
}
Anders Sjögren
Sortera strängar
• i sort_function() kan man använda strcmp()
_fstricmp, strcmp, strcmpi, stricmp
<STRING.H>
Declaration
int strcmp(const char * s1, const char * s2);
Remarks
strcmp performs an unsigned comparison of s1 to s2.
Return Value
These routines return an int value that is
-
< 0
== 0
> 0
if s1 < s2
if s1 == s2
if s1 > s2
Anders Sjögren
Sortera strängar
• i sort_function() kan man använda strcmp()
_fstricmp, strcmp, strcmpi, stricmp
<STRING.H>
Declaration
int strcmp(const char *s1, const char*s2);
Remarks
strcmp performs an unsigned comparison of s1 to s2.
Return Value
These routines return an int value that is
-
< 0
== 0
> 0
if s1 < s2
if s1 == s2
if s1 > s2
• OBS! Å Ä Ö
Anders Sjögren
Sortera strängar
• i sort_function() kan man använda strcoll()
strcoll
<STRING.H>
Compares two strings
Declaration
int strcoll(char *s1, char *s2);
Remarks
strcoll compares the string *s1 to the string *s2,
according to the collating sequence set by setlocale().
Return Value
strcoll returns a
- < 0 if s1 <
- == 0 if s1 ==
- > 0 i f s1 >
value that is
s2
s2
s2
• OBS! Å Ä Ö
Anders Sjögren
Sökning i strängar
_fstrstr, strstr
<STRING.H>
Finds the first occurrence of a substring in another string
Declaration
char *strstr(const char *s1, const char *s2);
Remarks
strstr scans s1 for the first occurrence of the substring s2.
Return Value
-
On success, strstr returns a pointer to the element in s1 where
s2 begins (points to s2 in s1).
On error (if s2 does not occur in s1), strstr returns null.
Anders Sjögren
Slut
Anders Sjögren