forked from CoolerVoid/C
-
Notifications
You must be signed in to change notification settings - Fork 0
/
estruturas.txt
2326 lines (1973 loc) · 67 KB
/
estruturas.txt
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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<title>Estruturas em C por Cooler_</title>
<meta name="author" content="BotecoUnix" />
<meta name="generator" content="VIM" />
<style type="text/css">
<!--
body {background-color:#31393A;
background-image: url("orange.jpg");
background-repeat: no-repeat;
background-position: right top;
background-attachment: scroll;
color:#ffffff; white-space:pre; font-family: monospace; font-size:1em;}
A {text-decoration:underline; color:#ffffff;}
A:hover {text-decoration: none; color:#000000; background-color:#ffffff;}
div.atitle {border:0px; margin:0px; padding:0px; font-size:1em; font-weight:bold;}
div.acode {border:solid 1px #00ff00; background-color:#c3c3c3; color:#000000; margin: 1em; padding:1em; font-family: monospace; font-size:0.9em;}
div.alist {border:solid 1px #00ff00; margin: 1.5em; padding:1em; font-family: monospace; font-size:0.9em;}
.blogs {font-size: 10pt; width: 49em; padding: 5px;}
.blogs A {color: lightblue; padding-top: 0;}
.blogs A:hover {color: #000000; background-color:lightblue; padding-top: 0;}
.blogs H1 {font-size: 11pt; margin-bottom: 0;}
.mkdsays {background: #404040;;}
.code {width: 46em; overflow: auto; border: 1px dotted darkgrey; padding: 5px;}
//-->
</style>
</head>
<body>
<pre>
<div class="blogs">
____ _ _ _ _
| _ \ | | | | | | (_)
| |_) | ___ | |_ ___ ___ ___ | | | |_ __ ___ __
| _ < / _ \| __/ _ \/ __/ _ \| | | | '_ \| \ \/ /
| |_) | (_) | || __/ (_| (_) | |__| | | | | |> <
|____/ \___/ \__\___|\___\___/ \____/|_| |_|_/_/\_\
<FONT FACE="Verdana" COLOR="#00C7C2"> ...:::Ajudando povo Unix Like desde 2006:::...</FONT>
</div>
<div class="blogs">
# language: Portuguese
# Title: Estruturas de dados em C
cooler@malloc:~$ date
Qui Jul 22 13:45:46 BRT 2010
cooler@malloc:~$ cat struct.txt _ _
|\\ //|
today we study structures in C!! | \\ _ ///__ // | What i do Brain ?
_ _ | \\/_______\// |
/~\\ //~\ | Y | | ||Y |
| \\ // | | \| | |/ |
[ || || ] \ | o|o || /
] Y || || Y [ \__ \_--_ /___/
| \_|l,------.l|_/ | /.-\(____) /--.\
| >' `< | `--(______)----'
\ (/~`-^____^-'~\) / U// U / \
`-_>-_(@)__(@)_-<_-' / \ / / |
/ (__) \ ( .) / / /
\___/__\___/ `.`' / \ ART and CODE by Cooler_
/__`--'__\ |`-' |
/\(__,>-~~ __) | |__
/\//\\( `--~~ ) _l |--:.
'\/ <^\ /^> | ` ( < \\
_\ >-__-< /_ ,-\ ,-~~->. \ `:.___,/site: BotecoUnix.com.br
(___\ /___) (____/ (____) `---' Autor: Antonio "Cooler_"
contato: c00f3r[at]gmail.com
<b>Indice</b>
==========
00-Explanação ao Conteudo
01-Entendendo Estruturas "struct","Arrays with struct" e
"struct of struct" com exemplo biblioteca
02-Estruturas com ponteiros "Struct with Pointers", exemplo Agenda e Biblioteca
03-Alocação de memória com "struct" e "array",exemplo com Pilha "Stack".
04-Listas encadeadas, exemplo Lista Circular dublamente encadeada
05-Usando ENUM,Unions e typedef
06-Validação de dados com Regex e fazendo Parsers
07-Trabalhando com DB usando DBI e SQLite3
08-Bibliografia
09-Agradecimentos
<FONT FACE="Verdana" COLOR="#75F38F">
*Sugiro olhar o indice e ir dando Ctrl+F nos números dos capítulos
caso queira ver algo especifico...
*Para ler este paper,use um navegador decente como firefox,opera e manipule
o Zoom se o tamanho da fonte não estiver bom...
*Os códigos aqui escrítos em C tem motivos didáticos,são funcionais porem
caso forem implementados em sistemas reais,deve-se tomar cuidado com funções
perigosas como strcpy,printf tomar cuidado com Buffer Overflow,memory leaks
format string etc...
*caso de erro na compilação,na header troque ex: "stdio.h" por < stdio.h>
</FONT>
Não tive tempo de passar corretor ortográfico ;)
<b>00-Explanação ao Conteúdo</b>
=============================
Neste paper irei explicar como trabalhar com "Struct(estrutura)" e
com "arrays(vetores)" e com "pointers(apontadores)",também darei uma
explanação para alocação de memória usando "struct" e "arrays",Tentarei
passar exemplos interativos para que assim você leitor possa entender
melhor e não como um paradoxo.vamos ver Pilha,lista circular
sistemas de cadastros e um poco de persistência de dados. algumas
explicações tiradas do Livro do K&R "ansi C", e do livro "C prime plus"
e o livro do Tanembaum de sistemas operacionais para explicar relação
de pilha e lista circular com escalonamento,do mais uma singela explicação
de regex em C no final.
Motivação, muitos amigos me procurando buscando ajuda para soluções
simples em linguagem C,Este paper dedico ao meu amigo "_Mlk_" o Renan
e ao "delfo" para que eles quando entrarem em estrutura de dados não
tomem uma surra feia,á amigos como IAK e m0nad do BugSec grupo de estudos
que faço parte,grande abraço...
<b>01-Entendendo Estruturas "structs"</b>
===================================
Uma estrutura é uma coleção de uma ou mais variáveis possívelmente
de tipos diferentes colocadas juntas sob um unico nome para manipulação
conveniente.em outras palavras sendo direto você pode usar estruturas
desde um sistema simples de cadastro até arvores,grafos outras aplicações...
Antes de passar o exemplo vou explicar o programa que vou passar para nosso
estudo, que esta separado "por case"
entendendo o "struct"
struct livro {
char titulo[MAX];
char autor[MAX];
float valor;
};
nome da nossa estrutura é "livro"
e o array para armazenar dados chamamos de "livraria"
"struct livro livraria[MAX]"
Ilustrando estes dados
+--------------+ +----------------------+
| livraria[0] / =-------->> | livraria[0].titulo |-----> cada elemento tem array de N blocos
| \ \ +----------------------+ [][][][][][][][][][][]....
+--------------+ \ +---------------------+
|=--->> | livraria[0].autor |
| +---------------------+
| +---------------------+
|=--->> | livraria[0].valor |
+---------------------+
+--------------+ +----------------------+
| livraria[1] / =-------->> | livraria[1].titulo |
| \ \ +----------------------+
+--------------+ \ +---------------------+
|=--->> | livraria[1].autor |
| +---------------------+
| +---------------------+
|=--->> | livraria[1].valor |
+---------------------+
E assim vai dependendo dos cadastros inseridos...
isso justifica a listagem vide no código "case 1"
Já "case 2" adição de dados nada de mais apenas alocamos os dados na posição desejada
apartir de uma certa entrada do usuário..
"case 3" nada de mais mesma lógica da listagem porem usei função "strstr" da header "string"
para achar "livraria[?].titulo" igual ao que o cliente digitou.
"case 4" aqui seguimos mesma lógica da "case 3" para achar elemento para ser removido porem
logo que achamos,então usamos uma estrutura provisória apenas para alocar estrutura dados da
estrutura a ser removida, seguinto sequinte lógica
valor: [3][2][8][1][4]
elemento: 0 1 2 3 4
Suponhamos que foi escolhido elemento 2 para ser removido cujo valor é "8"
Então fazemos uma troca até o ultimo elemento ser aquele que foi escolhido a ser removido
1 [ 3 ] 1 [ 3 ] 1 [ 3 ] 1 [ 3 ]
2 [ 2 ] 2 [ 2 ] 2 [ 2 ] 2 [ 2 ]
3 [ 8 ] \ 3 [ 1 ] 3 [ 1 ] 3 [ 1 ]
4 [ 1 ] / 4 [ 8 ] \ 4 [ 4 ] 4 [ 4 ]
5 [ 4 ] 5 [ 4 ] / 5 [ 8 ] <---= então no fim da troca usamos "cont--"
só para constar o vetor não foi apagado de verdade
para tal feito sete o último vetor para "NULL"
isso justifica o uso do rotulo "pon" que usa mesma estrutura de "livraria"
index = numero do elemento do array
pon=livraria[index];
livraria[index]=livraria[index+1];
livraria[index+1]=pon;
outra forma
A B C
| | | | | |
|~~~~~| |~~~~~| | |
| | | | | |
| | | | | |
+-----+ +-----+ +-----+
Na lógica imaginamos como se fosse 3 copos sendo dois cheios e um vazio
para fazer a troca entre A e B,nada impossível com terceiro copo "c=b; b=a; a=c;"
E se só tive-se copo "A" e "B" ?
Tem uma forma diferente usando XOR "^", para usar swap
mas desta vez descarto esta forma, que em elementos comuns com INT seria
int a = 10;
int b = 20;
a = a ^ b:
b = a ^ b;
a = a ^ b;
está explicação do uso do XOR fica a créditos do mestre dos magos "I4K"
grande amigo do grupo que faço parte "BugSec",tem outras formas de fazer
a troca em fim programação nunca você tem uma opção unica opção...
Finalmente "case 5" aqui não tem muito truque, apenas chamamos a função "Qsort"
que usa o algoritmo de organização "sort" chamado "Quicksort",usamos a função
"sort_char" e "strcmp" para fazer comparação entre strings,da header
"string.h",Bom lembrando que sistema é "case sentive", "A" fica primeiro que
"a" valor convertido decimal de "A" é maior,caso queira criar sua própria função
quicksort procure na Rede algum material sobre o mesmo é muito fácil achar...
======================================== Code
/*
Catalogo de Livraria
Exemplo de como usar "Arrays of Struct" em C
Autor: Cooler_
contato: [email protected] , [email protected]
webSite: BotecoUnix.com.br
*/
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
#define MAX 100
void opcao_menu() {
int i;
char *banner[] = {
"-----------------------------------------------------------",
"Programa Livraria",
"coded by Cooler_",
"(1)Listar",
"(2)Adicionar ",
"(3)Procurar livro",
"(4)Remover livro",
"(5)Mostrar dados em Ordem Alfabética usando QuickSort",
"(6)Fim",
"-----------------------------------------------------------",
};
for(i=0; i<=9; i++) printf("%s\n",banner[i]);
}
int sort_char( const void *a, const void *b) {
return( strcmp(a,b) );
}
struct livro {
char titulo[MAX];
char autor[MAX];
float valor;
};
int main() {
int op=0;
struct livro livraria[MAX], pon;
int count=0;
int x,index;
char achar[MAX];
while(op!=6)
{
opcao_menu();
scanf("%d",&op); getchar();
switch(op)
{
case 1:
printf("Listando livros:\n");
for (index = 0; index < count; index++)
printf("%s de %s , valor: $%.2f\n", livraria[index].titulo,
livraria[index].autor, livraria[index].valor);
break;
case 2:
printf("Digite Titulo do livro.\n");
fgets(livraria[count].titulo,sizeof(livraria[count].titulo),stdin);
livraria[count].titulo[strlen(livraria[count].titulo)-1] = '\0';
printf("Digite o autor.\n");
fgets(livraria[count].autor,sizeof(livraria[count].autor),stdin);
livraria[count].autor[strlen(livraria[count].autor)-1] = '\0';
printf("Digite o valor.\n");
scanf("%f", &livraria[count++].valor);
while (getchar() != '\n') continue;
break;
case 3:
printf("Digite Titulo do livro a procurar.\n");
fgets(achar,sizeof(achar),stdin);
achar[strlen(achar)-1] = '\0';
for (index = 0; index < count; index++)
{
if(strstr(livraria[index].titulo, achar) != NULL)
printf("%s de %s , valor: $%.2f\n", livraria[index].titulo,
livraria[index].autor, livraria[index].valor);
}
break;
case 4:
x=1;
printf("Digite Titulo do livro a deletar.\n");
fgets(achar,sizeof(achar),stdin);
achar[strlen(achar)-1] = '\0';
for (index = 0; index < count; index++)
{
if(strstr(livraria[index].titulo, achar) != NULL)
{
printf("dado a ser removido \n %s de %s , valor: $%.2f\n", livraria[index].titulo,
livraria[index].autor, livraria[index].valor);
pon=livraria[index];
livraria[index]=livraria[index+1];
livraria[index+1]=pon;
x=0;
}
}
if(!x) count--;
break;
case 5:
printf("Listando livros em Ordem Alfabética:\n");
qsort((void *)livraria, count, sizeof(livraria[0]), sort_char);
for (index = 0; index < count; index++)
printf("%s de %s , valor: $%.2f\n", livraria[index].titulo,
livraria[index].autor, livraria[index].valor);
break;
}
}
return 0;
}
======================================== EOF
Mudando de assunto e se fosse uma estrutura dentro da outra ?
Obviamente podemos criar estruturas que contenham outras estruturas:
Um exemplo pratico eh:
struct boss {
float altura;
float peso;
char* nome;
int idade;
};
Isso define um novo tipo de variavel, chamada boss.
Podemos 'criar' uma pessoa da seguinte forma:
struct boss rotulo;
E podemos modificar os subvalores de rotulo:
rotulo.altura = 1.70;
rotulo.peso = 60;
rotulo.nome = "Dimitri Vashnov";
rotulo.idade = 18;
Obviamente podemos criar estruturas que contenham outras estruturas:
struct grupo {
struct boss chefe;
int tamanho;
};
Assim, poderiamos declarar dv o chefe o grupo assim:
struct grupo grupo_do_rotulo;
grupo_do_rotulo.chefe = rotulo;
grupo_do_rotulo.tamanho = 1;
Assim, a idade do chefe seria
grupo_do_rotulo.chefe.idade
<b>02-Pointers with Struct</b>
==========================
Agora o segundo exemplo apontadores com estruturas de vetores
"Pointers of structs",mesma lógica do anterior porem com ponteiros
agenda simples
========================================Code
#include <stdio.h>
#include <stdlib.h>
// by Cooler agenda exemplo, feita no ano de 2010
//limite cadastros
#define LIMITE 10
#define BUFFER 32
//macro Anti Bug do "new line" comum em alguns OS, 1 para ativar 0 para desativar
#define ANTBUG 1
struct agenda {
char nome[BUFFER];
int ra;
};
struct agenda list[LIMITE],carry;
struct agenda *lista=list;
int cmp(const void *a, const void *b)
{
//faz o casting para struct e verifica em ordem decrescente
struct agenda *ia = (struct agenda *)a;
struct agenda *ib = (struct agenda *)b;
return (ia->ra < ib->ra);
}
void banner()
{
puts("\ncode agenda by cooler\n digite numero da opção 0- exit 1 inserir ,2 remover , 3 listar , 4 listar em ordem de ra\n");
}
void inserir (int count)
{
if(count != LIMITE)
{
puts("\ndigite nome");
scanf("%s",lista[count].nome);
#if ANTBUG
getchar();
#endif
puts("\ndigite RA");
scanf("%d",&lista[count].ra);
#if ANTBUG
getchar();
#endif
}
else {
puts("agenda cheia");
}
}
void delete(int count)
{
int position=0,count3=0,count2=0;
puts("qual RA para remover cadastro ?\n");
scanf("%d",&position);
#if ANTBUG
getchar();
#endif
count3=count;
while(count)
{
if(lista[count].ra == position)
{
count2=count;
while(count2<count3)
{
carry=lista[count2];
lista[count2]=lista[count2+1];
lista[count2+1]=carry;
count2++;
}
break;
}
count--;
}
}
void listar(int count)
{
while(count)
{
printf("Nome: %s RA: %d position: %d\n",lista[count].nome,lista[count].ra,count);
count--;
}
}
int main()
{
int escolha=1,count=0;
while(escolha)
{
banner();
scanf("%d",&escolha);
#if ANTBUG
getchar();
#endif
switch(escolha)
{
case 1:
count++;
inserir(count);
break;
case 2:
delete(count);
count--;
break;
case 3:
listar(count);
break;
case 4:
qsort(list,count,sizeof(struct agenda),cmp);
listar(count);
break;
}
}
puts("saindo");
sleep(3);
return 0;
}
========================================Code
agora a biblioteca
exemplo
======================================== Code
/*
..:: Catalogo de Livraria ::..
:: Exemplo de como usar arrays of Struct com ponteiros em C
Autor: Antonio "Cooler_"
Contato: [email protected]
WebSite: BotecoUnix.com.br
BugSec.com.br
coolerlab.wordpress.com
*/
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
#define MAX 100
void opcao_menu() {
int i;
char *banner[] =
{
"-----------------------------------------------------------",
"Programa Livraria",
"coded by Cooler_",
"(1)Listar",
"(2)Adicionar ",
"(3)Procurar livro",
"(4)Remover livro",
"(5)Mostrar dados em Ordem Alfabética usando QuickSort",
"(6)Fim",
"-----------------------------------------------------------",
};
for(i=0; i<=9; i++) printf("%s\n",banner[i]);
}
int sort_char( const void *a, const void *b) {
return( strcmp(a,b) );
}
struct livro {
char titulo[MAX];
char autor[MAX];
float valor;
} estante[MAX];
// nosso ponteiro vai apontar para estante
int main(int args, char * argv[]) {
int op=0;
// dois apontadores
struct livro *livraria[MAX], *pon;
int count=0;
int x,index;
char achar[MAX];
while(op!=6)
{
opcao_menu();
scanf("%d",&op); getchar();
// apontamos para estante
livraria[count]=&estante[count];
switch(op)
{
case 1:
printf("Listando livros:\n");
for (index = 0; index < count; index++)
/*
repare que usaremos a seta "->" para determinar o membro que sera usado na estrutura
pode ser representado das formas (*st).x ou st->x
*/
printf("%s de %s , valor: $%.2f\n", livraria[index]->titulo,
livraria[index]->autor, livraria[index]->valor);
break;
case 2:
printf("Digite Titulo do livro.\n");
fgets(livraria[count]->titulo,sizeof(livraria[count]->titulo),stdin);
livraria[count]->titulo[strlen(livraria[count]->titulo)-1] = '\0';
printf("Digite o autor.\n");
fgets(livraria[count]->autor,sizeof(livraria[count]->autor),stdin);
livraria[count]->autor[strlen(livraria[count]->autor)-1] = '\0';
printf("Digite o valor.\n");
scanf("%f", &livraria[count]->valor);
while (getchar() != '\n') continue;
count++;
break;
case 3:
printf("Digite Titulo do livro a procurar.\n");
fgets(achar,sizeof(achar),stdin);
achar[strlen(achar)-1] = '\0';
for (index = 0; index < count; index++)
if(strstr(livraria[index]->titulo, achar) != NULL)
printf("%s de %s , valor: $%.2f\n", livraria[index]->titulo,
livraria[index]->autor, livraria[index]->valor);
break;
case 4:
x=1;
printf("Digite Titulo do livro a deletar.\n");
fgets(achar,sizeof(achar),stdin);
achar[strlen(achar)-1] = '\0';
for (index = 0; index < count; index++)
if(strstr(livraria[index]->titulo, achar) != NULL)
pon=livraria[index],livraria[index]=livraria[index+1],livraria[index+1]=pon,x=0;
if(!x,count--,puts("dado removido\n")) break;
else puts("não foi achado nada para remover\n");
break;
case 5:
printf("Listando livros em Ordem Alfabética:\n");
qsort((void *)estante, count, sizeof(estante[0]), sort_char);
for (index = 0; index < count; index++)
printf("%s de %s , valor: $%.2f\n", livraria[index]->titulo, livraria[index]->autor, livraria[index]->valor);
break;
}
}
return 0;
}
======================================== EOF
<b>03-Alocação de memória de estruturas e vetores</b>
=================================================
Para Alocação de memória em C,vamos usar a função "malloc()" que usa a "HEAP"
ilustrando o funcionamento da memória teremos.
_______
| .text | --> seu código em C fica nesse segmento
|-------|
| .data | --> nesse segmento váriaveis Global e static inicializadas ex: "int static x=1;"
|-------|
| |
| .bss | --> outras variáveis que não seja inicializadas global e static, "int static x"
| |
| | no final da BSS a heap.
| .heap | --> memória estática ou dinâmica em C para usalá vamos usar função "malloc()"
| | pode utilizar o sistema brk e sbrk.
| | mmap() para reservar potencialmente regiões não contíguas de memória
| | virtual para o espaço o processo de "endereço virtual.
|-------|
| |
|.stack | --> variáveis locais, endereços mais altos da memória,usa conceito LIFO,
| | pilha cresce para baixo...
+-------+
heap ea pilha são dinâmicos, ambos crescem em direções diferentes para o outro.
Isso minimiza o desperdício de espaço, permitindo que a pilha para ser maior se
a pilha é pequeno e vice-versa.
Cada bloco de memória ocupada do heap tem um cabeçalho (header) de 8 bytes
representado pela estrutura _HEAP_ENTRY que, como numa lista duplamente ligada,
aponta para o próximo bloco e para o bloco anterior.
Após esse header há outro header de 8 bytes do tipo _LIST_ENTRY quem também é
uma lista duplamente ligada. Esse header é usado para apontar para os segmentos
de memória livres.Por segmento me refiro a um bloco contínuo de memória virtual.
Stack __
w c(..)o (
\__(-) __)
/\ (
/(_)___)
w /|
| \
m m
vamos ilustrar isso com um programa,código não é meu...
eu apenas traduzi os comentários para ajudar o pessoal ;)
---------------------- Code
/*
* mem_sequence.c / ver 0x01 | (C)opyleft 2008 by oozie | http://blog.ooz.ie/
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Lists memory areas and their location in descending order.
*
* This program declares example variables in different memory locations, gets
* their addresses, sorts them and prints a list in descending order.
*
* The program is considered free software; you can redistribute and/or modify
* it under the terms of the GNU General Public License version 3 or any later
* version, as published by the Free Software Foundation; If you do modify it,
* please leave the information about the author unchanged. The full text of
* latest GPL licence is available at http://www.gnu.org/licences/gpl.txt
*/
#include "stdio.h"
#include "stdlib.h"
#define MEM_TYPES 5
#define STR_STACK "stack"
#define STR_HEAP "heap"
#define STR_BSS "bss"
#define STR_CONST "const's"
#define STR_CODE "code"
const char const_example[]="string constante";
struct memtype_ptr {
int *ptr;
char *str;
};
struct memtype_ptr type_pointer[MEM_TYPES];
char bss_example[]="uma variável global";
// usa duas estruturas para buble sort
void mem_xchg(struct memtype_ptr *a, struct memtype_ptr *b)
{
struct memtype_ptr tmpmemptr;
tmpmemptr.str = a->str;
tmpmemptr.ptr = a->ptr;
a->str = b->str;
a->ptr = b->ptr;
b->str = tmpmemptr.str;
b->ptr = tmpmemptr.ptr;
}
void print_sorted(int *heap_example, int stack_example)
{
int i,j;
// definido os nomes e seus endereços na tabela
type_pointer[0].str = STR_HEAP;
type_pointer[0].ptr = heap_example;
type_pointer[1].str = STR_BSS;
type_pointer[1].ptr = (int *)&bss_example;
type_pointer[2].str = STR_STACK;
type_pointer[2].ptr = &stack_example;
type_pointer[3].str = STR_CODE;
type_pointer[3].ptr = (int *)stack_example;
type_pointer[4].str = STR_CONST;
type_pointer[4].ptr = (int *)&const_example;
// usamos método bolha para organizar de forma decrescente
j=MEM_TYPES;
while(j--)
for(i=0; i<j; i++)
if(type_pointer[i].ptr < type_pointer[i+1].ptr)mem_xchg(&type_pointer[i],&type_pointer[i+1]);
// mostra a tabela
for (i = 0 ; i < MEM_TYPES; i++)
printf("%d.(0x%.8x) %s\n", i+1,(int )type_pointer[i].ptr,type_pointer[i].str);
return;
}
int main(void)
{
int *dyn_allocated, code_example;
// pega endereço da memória da função main()
code_example=(int )&main;
// alocação dinâmica par amostrar a HEAP
dyn_allocated=(int *)malloc(sizeof(int));
//mostra endereço de memória na ordem decrescente
print_sorted(dyn_allocated, code_example);
getchar();
return 0;
}
---------------------- EOF
exemplo do uso do malloc para alinhamento
para assim facilitar na depuração dos erros
---------------------- CODE
void * xmalloc (size_t size)
{
void *p;
p = malloc (size);
if (!p) {
perror ("xmalloc");
exit (EXIT_FAILURE);
}
return p;
}
---------------------- EOF
Agora um exemplo mais calmo usando Pilha e alocação de memória com "struct"
linha por linha comentada...
= Objetivo
Um deposito de Bebidas precisa manter o controle de caixas empilhadas
cada caixa tem no máximo 12 garrafas,faça um programa para cadastrar
nome da caixa,quantidade de garrafas e preço de cada garrafa,programa
deve ter opção de remover caixa empilhada e mostrar caixas empilhadas com
total de custo da caixa somando as garrafas...
======================================== Code
/*
Site: BotecoUnix.com.br
Autor: Antonio Cooler e-mail:[email protected]
Licença: BSD
Baseado nos ensinamentos do livro do K&R e do livro C completo e total
*/
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
// Número maximo de chars nas vars
#define MAX 30
// Número maximo de caixas
#define BOX 20
void opcao_menu()
{
int i;
char *banner[] = {
"--------------------------",
"Programa Pilha de caixas",
"coded by Cooler",
"(1)Listar Caixas Empilhadas",
"(2)Empilhar Caixa",
"(3)Desempilhar Caixa",
"(4)Sair do programa",
"--------------------------",
"> "
};
for(i=0; i<=7; i++) printf("%s\n",banner[i]);
}
// estrutura usada
typedef struct caixa {
char nome[MAX];
int garrafas;
float valor;
} caixa;
//pegando entrada do usuário e retorna com os mesmos
caixa adiciona_caixa()
{
caixa p;
printf("informe alguns dados\n");
printf("o Nome: \n");
fgets(p.nome, sizeof(p.nome), stdin);
p.nome[strlen(p.nome)-1] = '\0';
printf("A quantidade de garrafas:\n");
scanf("%d",&(p.garrafas));
// maximo de garrafas por caixa é 12 setamos isso aqui numa condição
p.garrafas=(p.garrafas>12)?12:p.garrafas;
printf("O preço:\n"); scanf("%f",&(p.valor));
return p;
}
int main()
{
int x,y,op=0;
float total;
// ponteiro da nossa estrutura
caixa *cad;
y=0;
// alocamos dados na memória
cad=(caixa *)calloc(BOX,sizeof(caixa));
while(op!=4)
{
opcao_menu();
scanf("%d",&op); getchar();
if(op==1)
{
// Mostra a lista de caixas
printf("\n Nome Garrafas Preço Total\n");
for(x=y-1; x>=0; x--) printf(" %6s %8d %12.2f %7.2f\n",
cad[x].nome,
cad[x].garrafas,
cad[x].valor,
total=cad[x].garrafas*cad[x].valor);
}
// Adiciona uma caixa e chama a função "adiciona caixa"
if(op==2) cad[y]=adiciona_caixa(),y++;
// remove caixa,subtrai o apontador da proxima adição de dados substitui o dado pelo
// Escolhido
if(op==3) y--;
}
free(cad);
return 0;
}
========================================== EOF
Algoritmo usado é chamado de Pilha,no exterior chamado de Stack "LIFO"
(que significa Last In, First Out).Poderia dar um exemplo
de escalonamento ou de processo só que iria almentar a curva de aprendizado.
Então escolhi a dedo um problema simples,qual melhor forma de aprender pilhas
"caixas em pilhadas!",está foi minha idéia...
explicando
Para funções de alocação de memória em C vamos usar seguintes funções
da Biblioteca “stdlib.h” “calloc”,”malloc” e “realloc”.Outra função
desta mesma “Lib” que vamos usar vai ser “rand” que nos retorna um
numero randômico para nosso teste.
o “calloc” retorna um apontador para um espaço de um vetor,o espaço
é inicializado por zero bytes
o “malloc” retorna um apontado para espaço de um objeto por um
tamanho indicado.
o “realloc” altera tamanho do objeto apontado para “p”.
Só para explicar melhor alocação de memória
uso de algumas funções da lib "stdlib"
========================================== Code
// Autor: Cooler
// Exemplo de alocação dinâmica usando vetores
// Site:httṕ://BotecoUnix.com.br
// Biblioteca padrão de entrada e saida
#include "stdio.h"
// Biblioteca para alocação de memória e outras tarefas
#include "stdlib.h"
int main() {
int i,*v,*m;
printf("vetor iniciando usando calloc\n");
// alocamos na memoria no vetor "v" 5 blocos sendo "int"
// repare o uso do "sizeof" ele produz o número de bytes
// exigidos para armazenar em um objeto do tipo do seu operando
v=(int *)calloc(5,sizeof(int));
// atribuimos valores qualquer usando função rand
for(i=0; i<5; i++) v[i]=rand()%100;
for(i=0; i<5; i++) printf("%3d",v[i]);
printf("\nvetor ficando maior usando realloc\n");
// agora alteramos o tamanho da memoria alocada para dez
// inves de "5" usando funçao realloc
v=(int *)realloc(v,10*sizeof(int));
for(i=5; i<10; i++) v[i]=rand()%100;
for(i=0; i<10; i++) printf("%3d",v[i]);
printf("\nvetor deixando menor usando realloc\n");
//aqui deixamos de 10 para 3 valor de blocos do vetor
v=(int *)realloc(v,3*sizeof(int));
for(i=0; i<3; i++) printf("%3d",v[i]);
//agora vamos usar malloc
printf("\nAgora iniciando um vetor com malloc\n");
m=(int*)malloc(sizeof(int)*10);
for(i=0; i<10; i++) m[i]=rand()%100;
for(i=0; i<10; i++) printf("%3d",m[i]);
// mostrando o endereço alocado por "m"
printf("\nEndereço de 'm' é : %p \n", m);