Flerdimensionella vektorer Två-dimensionella vektorer Två

Flerdimensionella vektorer
Två-dimensionella vektorer
• I C kan man deklarera vektorer av alla typer,
inklusive vektorer av vektorer. På så vis kan
man skapa vektorer i flera dimensioner.
int a[100]; /*en endimensionell vektor*/
int b[2][7]; /*en två-dimensionell vektor*/
int c[6][2][5];/*en tredimensionell vektor*/
• Det är lättast att tänka på två-dimensionella
vektorer som en matris, med rader och kolumner.
• Deklarationen int a[3][5] kan ses på
följande vis:
• Initiering sker på liknande sätt som med
endimensionella vektorer.
int a[2][2] = {{1, 2}, {4, 0}};
• I minnet lagras dock flerdimensionella vektorer
kontinuerligt.
148
Två-dimensionella vektorer
149
Bubble sort
#include <math.h>
#include <stdio.h>
#define N 5
#define M 3
int main(void) {
double A[M][N];
int i, j;
for (i=0; i<M; i++) {
for (j=0; j<N; j++) {
A[i][j] = i*N+j;
printf("%4.0f", A[i][j]);
}
printf("\n"); /*Ny rad för varje rad i A */
}
}
void swap(int *a, int *b) {
int tmp;
tmp = *a;
*a = *b;
*b = tmp;
}
void bubble(int v[], int n) {
int i=0, j, swaped=1;
while(swaped) {
swaped=0;
for (j=0; j<n-i-1; j++)
if (v[j] > v[j+1]) {
swap(&v[j], &v[j+1]);
swaped=1;
}
i++;
}
}
150
Utskrifter till skärm
151
Flaggor till printf
• Utskrifter sker med printf funktionen.
#include <stdio.h>
int printf(const char* format, ...);
• Returnerar: Antalet utskrivna tecken om OK,
annars negativt värde.
• Första argumentet, format, anger vad som skall
skrivas ut och hur det skall skrivas ut.
• I format-strängen kan konverteringsspecifikationer
anges som beskriver hur följande argument skall
tolkas och konverteras.
int a = 3;
printf("%s\n","Hello world!");
printf("a har värdet %d\n",a);
152
[]
flaggan behöver inte anges.
|
eller
x
bredd på fältet
y
antalet decimaler som skall skrivas ut
z
antalet siffror i exponenten som skall skrivas ut.
vänsterjusterat
space mellanslag om tecken saknas
+
skriver ut + eller - före nummer
0
fyller ut med 0:or.
#
alternativ formatering.
153
1
Flaggor till printf
%[-][x]c
%[-][x]s
%[ |+][-][0][x]d
%[ |+][-][0][x]u
%[ |+][-][0][x]o
%[ |+][-][0][x]x
%[ |+][-][0][x]X
%[ |+][-][0][x][.y]f
%[ |+][-][0][x][.y]lf
%[ |+][-][#][0][x][.y][+z]e
%[ |+][-][#][0][x][.y][+z]E
%[ |+][-][#][0][x][.y][+z]g
%[ |+][-][#][0][x][.y][+z]G
Exempel på printf
chars
strings
decimal
unsigned decimal
octal
hexadecimal (with a,b,...)
hexadecimal (with A,B,...)
float
double
scientific notation (with e)
scientific notation (with E)
same as f or e, depending on the value.
same as f or E, depending on the value.
#include <stdio.h>
int main(void) {
int i1 = -3;
int i2 = 5;
char c1 = ’c’;
double f1 = -2.0;
double f2 = 3.3;
printf("%-10s%10s\n", "Variabel", "Värde");
printf("--------------------\n");
printf("%-10s%+10d\n",
"i1", i1);
printf("%-10s% 10d\n",
"i2", i2);
printf("%-10s%10c\n",
"c1", c1);
printf("%-10s%+10.2f\n", "f1", f1);
printf("%-10s%+10.2+2e\n","f2", f2);
return 0;
}
154
Exempel på printf
155
Inläsning från tangentbord
• Inläsning från tangentbordet sker vanligtvis med
scanf.
• Ger utskriften:
Variabel
Värde
-------------------i1
-3
i2
5
c1
c
f1
-2.00
f2
+3.30e+00
#include <stdio.h>
int scanf(const char* format, ...);
• Returnerar: Antalet lyckosamma matchningar. Vid
fel EOF.
• Första argumentet, format, anger hur det som läses
in skall formateras.
• Efterföljande argument anger adresser (pekare) till
minnesutrymme för det inlästa datat.
int i;
char c;
double d;
scanf("%d%c%lf", &i, &c, &d);
156
Exempel på scanf
157
Fler strängfunktioner
int i;
char c;
char s[15];
scanf("%d,%*s %% %c %5s %s", &i, &c, s, &s[5]);
#include <stdio.h>
int sprintf(char *s, const char* format, ...);
• Med insträngen
45, ignore_this % C read_in_this**
• lagras 45 i i, ’C’ i c och read_ lagras i s[0] till
s[4] och \0 i s[5].
• Därefter lagras in_this** i s[5] till s[13] och
\0 i s[14].
158
• Returnerar: Antalet utskrivna tecken om OK,
annars negativt värde.
• sprintf fungerar på samma sätt som printf
med den skillnaden att resultatet skrivs till en
sträng, s, istället för till skärmen.
#include <stdio.h>
int sscanf(char* s, const char* format, ...);
• Returnerar: Antalet lyckosamma matchningar. Vid
fel EOF.
• scanf läser text från en sträng och inte från
tangentbordet.
159
2
Dynamisk minnesallokering
Dynamisk minnesallokering
• Allokera minne för de variabler man behöver och
frigör minne när man är klar.
• För att allokera minne finns i C, de inbyggda
funktionerna malloc och calloc.
• malloc allokerar size bytes med minne.
• För att allokera minne som räcker för en viss
mängd data och datatyp invänds oftast sizeof.
#include <stdlib.h>
void *malloc(size_t size);
void *calloc(size_t nelem, size_t size);
• Här allokeras minne för en heltalsvektor med
längden 10.
• Observera att vi också gör en typecast från void*
till int*. Detta är inte nödvändigt, men är bra
programmeringsstil.
• v[i] kan användas p.s.s. som om man gjort
deklarationen v[10].
int *v = (int*)malloc(10*sizeof(int));
• Returnerar: En pekare till allokerat minne om OK,
annars NULL
• Typen size_t är i ANSI C definierad till
unsigned int. Vanligtvis är typedef
använd i stdlib.h.
160
161
Dynamisk minnesallokering
Dynamisk minnesallokering
• calloc allokerar nelem element av storleken
size.
• calloc initierar det allokerade minnets alla bitar
till 0;
• Motsvarande exempel för calloc blir:
• Minne som är dynamiskt allokerat lämnas inte
automatiskt tillbaka till systemet.
#include <stdlib.h>
void free(void* ptr);
• Funktionen free används för att explicit lämna
tillbaka minne.
int *v = (int*)calloc(10, sizeof(int));
int *p = (int*)malloc(10*sizeof(int));
...
free(p);
• Allokerat minne är inte knutet till en specifik
pekarvariabel.
• Om man förlorar referensen till allokerat minne
kan man inte sedan referera det eller frigöra det.
162
163
Dynamisk minnesallokering
Strängexempel
int* new_int_array(int n) {
int *v;
v = (int*)malloc(n*sizeof(int));
return v;
}
#include <stdlib.h>
#define MAX_STR_LEN 20
int main(void) {
char s[] = "I love pointers";
char *p;
p = (char*)malloc(MAX_STR_LEN*sizeof(char));
strncpy(p, s, MAX_STR_LEN);
free(p);
}
int main(void) {
int *p;
p = new_int_array(10);
p = new_int_array(10); /* memory lost!!! */
free(p);
}
• Bild just innan free anropas.
s
p
164
I
l o v e
p o i n t e r s \0
I
l o v e
p o i n t e r s \0 ? ? ? ?
165
3
Argument till main()
Echo exempel
• Två argument, vanligtvis kallade argc och argv
kan användas med main() för kommunikation med
operativsystemet.
• argc anger antalet argument på kommandoraden.
• argv är en vektor med pekare till strängar
innehållande respektive argument.
• Kommandot, eller programnamnet, är alltid första
argumentet.
int main(int argc, char *argv[]) {
...
}
166
#include <stdio.h>
int main(int argc, char *argv[]) {
int i;
for (i=1; i<argc; i++) {
printf("%s", argv[i]);
if (i < argc-1)
printf(" ");
else
printf("\n");
}
return 0;
}
167
Echo exempel
• Om det tidigare exemplet döpts till my_echo och
kompilerats på C: kan ett
• exempel vid kommandopromten bli:
C:> my_echo I love C
I love C
C:>
• I minnet kommer det att se ut så här:
168
4