Buscar

Tipos de Dados em C e C++

Prévia do material em texto

APOSTILA: LINGUAGENS DE PROGRAMAÇÃO C E C++ 
Angelo Passaro Página V.1 Segunda revisão / 2002 
 
VV.. TTIIPPOOSS DDEERRIIVVAADDOOSS 
As linguagens C e C++ permitem que tipos intrínsecos sejam agrupados para formar tipos de dados 
derivados. As formas básicas de tipos de dados agrupados são ARRAYS e STRUCTURES. Estes tipos de dados 
podem ser formados por outros dados derivados. 
Ponteiros e Classes também são tipos derivados, mas devido a importância que os ponteiros assumem para 
o C e o C++ e a de classes para o C++, estes serão tratados em capítulos separados. 
V.A. Arrays (Vetores e matrizes) 
Um array é uma agrupamento contínuo de um ou mais elementos de um mesmo tipo (o que inclui tipos 
intrínsecos, structures (ou classes) ou ponteiros). 
Arrays (ou seja vetores e matrizes) podem ser estáticos (número de elementos determinado em tempo de 
compilação) ou dinâmicos (número de elementos determinado em tempo de execução). A forma de declaração e 
dimensionamento de vetores e matrizes dinâmicos será apresentada somente após a apresentação de ponteiros (no 
capítulo VI). 
V.A.1. Declaração de Arrays V.A.1 
Sintaxe de declaração de arrays estáticos: 
tipo identificador_array [ n ] ; 
tipo identificador_ array [ n ] [ m ] ...[ k ]; 
onde tipo é qualquer tipo válido da linguagem (intrínseco ou derivado), n, m ..., k são expressões constantes que 
representam o número de elementos em cada dimensão (vetor é um array de uma dimensão e matriz é um array de 
duas dimensões). 
O primeiro índice indicado (o mais próximo ao identificador) especifica a maior dimensão do array. Isto 
não significa que o primeiro índice deve ser maior que os demais, mas sim que o armazenamento do array na 
memória é feito variando mais rapidamente o índice da direita e mais lentamente o da esquerda. 
 
Exemplos: 
short int a [ 5 ]; // declaração de um array de inteiros de dimensão 1 (vetor) com 5 componentes. 
float d [ 3 ] [ 2 ]; // declaração de um array de floats de dimensão 2 com 3x2 (6) componentes. 
char c [ 5 ] [ 3 ] [ 5 ]; // declaração de um array de chars de dimensão 3 com 5x3x5 componentes. 
V.A.2. Inicialização de Arrays V.A.2 
Da mesma forma que identificadores de tipos intrínsecos podem ser declarados e definidos (inicializado 
com um valor), os arrays também podem ser inicializados na declaração (ou seja, o array é definido na declaração). 
Os valores de inicialização para cada dimensão podem ser especificados de duas maneiras : 
• dimensão a dimensão, com os valores dos elementos colocados entre chaves ( { } ), partindo da “maior 
dimensão”, ou seja a primeira dimensão especificada; dentro do par de chaves, cada valor é separado 
por uma vírgula; 
• considerando o array como sendo de uma única dimensão, com os valores dos elementos especificados 
em seqüência, variando mais rapidamente a dimensão menor e menos rapidamente a dimensão maior. 
Para exemplificar estas duas formas de inicializar um array, vamos utilizar as declarações da seção V.A.1. 
 
Exemplos: 
// o array a com cinco componentes do tipo short int são inicializados com os valores 
APOSTILA: LINGUAGENS DE PROGRAMAÇÃO C E C++ 
Angelo Passaro Página V.2 Segunda revisão / 2002 
 
// a[0] = 1000, a[1] = 1001, a[2] = 10002, a[3] = 1003 e a[4] = 10004 
short int a [ 5 ] = { 1000, 1001, 1002, 10003, 10004 }; 
ou 
short int a [ ] = { 1000, 1001, 1002, 10003, 10004 }; // ou seja, neste caso não é necessário 
 // especificar a maior dimensão do array. 
 
float d [ 3 ] [ 2 ] = { { 30, 31 }, { 20, 21 }, { 10, 11 } }; 
ou 
float d [ ] [ 2 ] = { { 30, 31 }, { 20, 21 }, { 10, 11 } }; // novamente, não é necessário especificar a 
 // maior dimensão do array 
ou 
float d [ ] [ 2 ] = { 30, 31, 20, 21, 10, 11 }; // novamente, não é necessário especificar a 
 // maior dimensão do array 
ou 
float d [ ] [ 2 ] = { 30, 31, // neste caso, a visualização da matriz de 
 20, 21, // 3 linhas x 2 colunas se torna mais clara. 
 10, 11 
 }; // fim da definição da matriz d 
ou, ainda, 
float d [ ] [ 2 ] = { {30, 31}, // neste caso, a visualização da matriz de 
 {20, 21}, // 3 linhas x 2 colunas se torna mais clara. 
 {10, 11} 
 }; // fim da definição da matriz d 
 
char c [ 5 ] [ 3 ] [ 5 ] = 
{ 
 {{0,1,2,3,4}, {5, 6,7,8,9}, {10,11,12,13,14}}, 
 {{0,1,2,3,4}, {5, 6,7,8,9}, {10,11,12,13,14}}, 
 {{0,1,2,3,4}, {5, 6,7,8,9}, {10,11,12,13,14}}, 
 {{0,1,2,3,4}, {5, 6,7,8,9}, {10,11,12,13,14}}, 
 {{0,1,2,3,4}, {5, 6,7,8,9}, {10,11,12,13,14}}, 
} ; // fim da definição de c 
ou 
char c [ ] [ 3 ] [ 5 ] = 
{ 
 {{0,1,2,3,4}, {5, 6,7,8,9}, {10,11,12,13,14}}, 
 {{0,1,2,3,4}, {5, 6,7,8,9}, {10,11,12,13,14}}, 
 {{0,1,2,3,4}, {5, 6,7,8,9}, {10,11,12,13,14}}, 
 {{0,1,2,3,4}, {5, 6,7,8,9}, {10,11,12,13,14}}, 
 {{0,1,2,3,4}, {5, 6,7,8,9}, {10,11,12,13,14}}, 
 {{0,1,2,3,4}, {5, 6,7,8,9}, {10,11,12,13,14}}, 
} ; // fim da definição de c 
ou 
 
char c [ 5 ] [ 3 ] [ 5 ] = 
{ 
 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 , 
 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 , 
APOSTILA: LINGUAGENS DE PROGRAMAÇÃO C E C++ 
Angelo Passaro Página V.3 Segunda revisão / 2002 
 
 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 , 
 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 , 
 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 
}; // fim da definição de c 
 
ou 
char c [ ] [ 3 ] [ 5 ] = 
{ 
 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 , 
 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 , 
 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 , 
 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 , 
 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 
}; // fim da definição de c 
V.A.3. Acesso aos componentes de um array utilizando índices 
Os elementos individuais de um array podem ser endereçados por índices, os quais correspondem a posição 
do elemento desejado no array. O operador de subscrito ( [ ] ) é utilizado para o acesso a um determinado elemento 
do array. A posição de memória em que o elemento está armazenado é determinada automaticamente em função do 
índice do elemento e do número de bytes utilizados para o armazenamento do tipo dos elementos. 
Observação: 
Todos os índices de arrays em C e C++ começam a ser contados a partir (e inclusive) 
do zero. Assim, o primeiro componente de um array unidimensional cujo identificador 
é vet será vet [0]. 
 
Como exemplo, vamos inicializar (não na declaração, como feito na seção V.A.2) um vetor de inteiros com 
os 100 primeiros números naturais. 
 
Exemplo: 
int n_naturais [100]; // somente declaração 
for (int i = 0; i < 100; n_naturais[i] = i + 1, i++); 
 
Exercícios: 
1. Faça a inicialização utilizando um laço while. 
2. Faça a inicialização na própria declaração. 
3. Implemente, com todos os detalhes, um programa que armazene os primeiros 1000 números naturais 
num vetor e faça a soma desses números. Implemente umasaída para apresentar a soma. 
4. Implemente, com todos os detalhes, um programa que armazene os primeiros 50 números naturais num 
vetor e faça o produto desses números. (Atenção à declaração do tipo de variável que irá armazenar a 
produtória. Aproveite para verificar a necessidade de uso do operador cast). 
5. Faça um programa que some duas matrizes (arrays bidimensionais) de dimensões 6x4. Fixe o valor dos 
elementos das duas matrizes na inicialização e faça a soma num laço for. 
ATENÇÃO à soma de matrizes : Os elementos da matriz soma são obtidos fazendo soma
 ij = aij + bij 
APOSTILA: LINGUAGENS DE PROGRAMAÇÃO C E C++ 
Angelo Passaro Página V.4 Segunda revisão / 2002 
 
V.A.4. O armazenamento de arrays na memória 
As linguagens C e C++ suportam, diretamente, somente arrays de dimensão 1. Para formar arrays de 
dimensão mais elevada (arrays multidimensionais) utilizam-se vetores de vetores (lembrem-se da definição de array 
no início da seção). Por outro lado, em C e C++, ao contrário do que ocorre com muitas outras linguagens, não 
existe um limite teórico para o número de dimensões de um array. Os arrays componentes em um array de arrays é 
denominado subarray. 
Arrays são armazenados por linha em C e C++. A figura V.1 representa a forma de armazenamento dos 
arrays declarados na seção V.A.1. Estude a figura com atenção. 
short int a [ 5 ] ;
float d [ 3 ] [ 2 ] ;
elemento 1 elemento 5elemento 4elemento 3elemento 2
a [ 0 ] a [ 1 ] a [ 2 ] a [ 3 ] a [ 4 ]
2 bytes 2 bytes 2 bytes 2 bytes 2 bytes
elemento 1,1 elemento 3,1elemento 2,2elemento 2,1elemento 1,2
d [ 0 ] [ 0 ]
4 bytes
elemento 3,2
d [ 2 ] [ 1 ]d [ 2 ] [ 0 ]d [ 1 ] [ 1 ]d [ 1 ] [ 0 ]d [ 0 ] [ 1 ]
4 bytes 4 bytes 4 bytes 4 bytes4 bytes
subarray
char c [ 5 ] [ 3 ] [ 5 ] ;
elemento 1,1,1 elemento 1,1,2
c [ 0 ][ 0 ][ 0 ]
1 byte
c [ 0 ][ 0 ][ 1 ]
elemento 1,1,5
c [ 0 ][ 0 ][ 4 ]
1 byte
elemento 1,2,1
c [ 0 ][ 1 ][ 0 ]
1 byte
elemento 1,2,5 elemento 1,3,1
c [ 0 ][ 2 ][ 0 ]c [ 0 ][ 1 ][ 4 ]
1 byte 1 byte1 byte
subarray
... ...... ...
elemento 1,3,5 elemento 2,1,1
c [ 1 ][ 0 ][ 0 ]c [ 0 ][ 2 ][ 4 ]
1 byte 1 byte
elemento 5,3,5
c [ 4 ][ 2 ][ 5 ]
1 byte
 
Figura V.1 : Esquema do armazenamento de arrays na memória 
 
Os endereços de memória crescem do primeiro elemento para o último. Assim o endereço de memória em 
que está armazenado o primeiro elemento é menor que o do segundo, que por sua vez é menor que o do terceiro, e 
assim por diante. 
Para efeito de comparação, vamos imaginar que a posição de memória em que o primeiro elemento do 
vetor de inteiros a é armazenado seja representada pelo valor 100 (este é o endereço). O segundo elemento vai estar 
armazenado na posição 102 (lembrem-se que um short int ocupa dois bytes de memória (ou duas posições de 
memória). O terceiro elemento estará armazenado na posição 104 e assim por diante. Por outro lado, se declaramos 
um vetor de 5 posições de doubles (cada double ocupa 8 bytes de memória ou 8 posições de memória): 
double a[5]; 
e o primeiro elemento encontra-se na posição 100, então, o segundo elemento vai ser localizado na posição 108 e o 
terceiro na posição 116. Isto ocorre devido à diferença do número de bytes necessário para representar um número 
short int de um número double. O compilador se encarrega de alocar a memória corretamente no caso de arrays 
estáticos e o programa automaticamente identifica a posição de memória em que cada elemento pode ser encontrado 
pelo tipo de dados armazenados no vetor (o que é definido pela declaração, seção V.A.1). 
V.A.5. Strings como vetores de caracteres 
Um dos usos mais freqüentes de arrays é o armazenamento de seqüência de caracteres (ou “strings”). A 
linguagem C++ inclui, na biblioteca padrão, uma classe para strings. 
Uma seqüência de caracteres é formada por um array unidimensional de caracteres (char), terminadas por 
um caracter de seqüência de escape, \0. Como conseqüência, uma seqüência de caracteres deve sempre ser definida 
com um elemento a mais que o conjunto de caracteres da seqüência. 
APOSTILA: LINGUAGENS DE PROGRAMAÇÃO C E C++ 
Angelo Passaro Página V.5 Segunda revisão / 2002 
 
Uma seqüência de caracteres pode ser inicializada caracter a caracter, de forma análoga ao que foi 
apresentado na seção V.A.2. Neste caso, não se pode esquecer de incluir o caracter ‘\0’ no final da seqüência. Outra 
forma de inicializar uma seqüência de caracteres é utilizando uma constante literal (“string literal”). Neste caso, o 
caracter ‘\0’ é incluído automaticamente no final da seqüência. 
A biblioteca padrão da linguagem C incorpora um conjunto de funções que permitem manipular strings 
(strcpy(), strcmp(), strcat(), strchr(), dentre outras). Tais funções podem também ser utilizadas em C++. 
 
Exemplos: 
char mensagem[9] = { ‘m’, ‘e’, ‘n’, ‘s’, ‘a’, ‘g’, ‘e’, ‘m’, ‘\0’}; 
ou 
char mensagem[ ] = { ‘m’, ‘e’, ‘n’, ‘s’, ‘a’, ‘g’, ‘e’, ‘m’, ‘\0’}; 
ou 
char mensagem[9] = “mensagem”; 
ou 
char mensagem[ ] = “mensagem”; 
 
char mensagem[8] = “mensagem”; // ERRO! a string não é suficiente para armazenar o 
 // caracter ‘\0’ 
V.B. Structures 
Uma structure é um agrupamento de um ou mais objetos (de tipos intrínsecos ou derivados). Ao contrário 
do que ocorre com arrays, que só permitem agrupar objetos do mesmo tipo, uma structure permite agrupar objetos 
de tipos diferentes. Os objetos individuais que compõem a structure recebem a denominação de membros. 
Structures são utilizadas para agrupar um conjunto de dados que, juntos, apresentam um significado (uma 
unidade) na aplicação (software). 
V.B.1. Declaração de structures V.B.1 
Sintaxe: 
struct denominacao_estrutura {tipo_e_identificador_dos_membros} identificador; 
onde denominação_estrutura é uma espécie de rótulo pelo qual a structure pode ser identificada, 
tipo_e_idenficador_dos_membros é uma lista contendo o tipo e o identificador dos dados membros da structure. 
O identificador é opcional (neste caso, fica declarada a estrutura da struct, mas nenhuma variável desse tipo 
é declarada. Nos exemplos a seguir são declaradas as estruturas de 3 diferentes structures. Declarações de objetos do 
tipo structure são apresentadas nos exemplos da seção V.B.2. 
 
Exemplos: 
struct endereco 
{ 
char rua [256]; // armazena o nome da rua 
unsigned int numero; 
char cidade [30]; 
unsigned long int cep; 
} ; // fim da declaração da struct endereco 
 
struct data 
{ 
unsigned char dia, mes; 
APOSTILA: LINGUAGENS DE PROGRAMAÇÃO C E C++ 
Angelo Passaro Página V.6 Segunda revisão / 2002 
 
unsigned short int ano; 
}; // fim da declaração da struct data 
 
struct pessoa 
{ 
char nome [128]; 
endereco residencia; // a struct endereço, cujo identificador é residência, armazena 
 // o endereço residencial da pessoa 
endereco comercial; // a struct endereço, cujo identificador é comercial, armazena 
 // o endereço comercial da pessoa 
data nascimento; // armazena a data de nascimento 
}; // fim da declaração da struct pessoa 
 
V.B.2. Inicialização de Structures V.B.2 
Da mesma forma que identificadores de tipos intrínsecos e arrays podem ser declarados e definidos 
(inicializado com um valor), as structures também podem ser inicializadas na declaração (ou seja, a structureé 
definida na declaração). A inicialização ocorre na ordem de declaração dos membros. 
A seguir seguem alguns exemplos de inicialização de structures dos tipos declarados na seção V.B.1. 
 
Exemplos: 
 
// declarando e definindo 
struct endereco 
{ 
char rua [256]; // armazena o nome da rua 
unsigned int numero; 
char cidade [30]; 
unsigned long int cep; 
} end = { “Rua Balalaica”, 12222, “São Paulo”, 12222000}; 
 
// definindo (supõe-se declarada a struct endereco) 
endereco novo_end = { “Av. BlaBla da Silva”, 000, “Seilá”, 00000000}; 
 
// definicao da data com identificador dia_formatura 
data dia_formatura = {30,2,2000}; 
 
// definição de uma pessoa com identificador Joao_da_Silva 
// note-se que o conteúdo das structs residencial e nascimento foram inicializados colocando 
// os dados membros das structs entre chaves (bloco). 
// Contudo, essas chaves não são necessárias, como mostrado na inicialização da struct comercial. 
 
pessoa Joao_da_Silva = { “João José da Silva”, { “Av. BlaBla da Silva”, 000, “Seilá”, 00000000}, 
 “Rua 1”, 333, “Seilá”, 01000000, {28,02,1900}}; 
ou, 
pessoa Joao_da_Silva = { “João José da Silva”, “Av. BlaBla da Silva”, 000, “Seilá”, 00000000, 
 “Rua 1”, 333, “Seilá”, 01000000, 28,02,1900}; 
APOSTILA: LINGUAGENS DE PROGRAMAÇÃO C E C++ 
Angelo Passaro Página V.7 Segunda revisão / 2002 
 
V.B.3. Acesso aos membros de uma structure 
O acesso aos dados membros de uma structure é feito utilizando o operador de membro de structure (., 
seção III.D.2). O operador é posicionado entre o identificador da structure e o identificador do membro, como 
apresentado a seguir. 
 
Sintaxe: 
identificador_struct . identificador_membro 
 
Para exemplificar o acesso a dados membros de structures, são utilizadas as declaração e inicializações 
apresentadas nas seções V.B.1 e V.B.2. 
 
Exemplos: 
// acessando os dados membros da struct data 
unsigned short int a; 
unsigned char d, m; 
d = dia_formatura . dia; 
m = dia_formatura . mes; 
a = dia_formatura . ano; 
 
// acessando os dados membros da struct endereço 
char r [500], cid [500]; 
unsigned int n; 
unsigned long int cep; 
 
n = novo_end . numero; 
cep = novo_end . cep; 
strcpy ( r, novo_end . rua); // note o uso da função strcpy para copiar o conteúdo da string 
 // (ou melhor, array unidimensional de caracteres) rua, para 
 // o array r 
 
strcpy ( cid, novo_end . cidade); // note, novamente, o uso da função strcpy para copiar o 
 // conteúdo da string cidade para o array cid. 
 
// acessando os dados membros da struct pessoa 
char nom [500], rres [500], cidres [500], rcom[500], cidcom[500]; 
unsigned int nres, ncom; 
unsigned long int cep; 
unsigned short int a; // ATENÇÃO : nestes exemplos utilizamos identificadores curtos. 
unsigned char d, m; // Contudo, acostumem-se a usar identificadores que tenham algum 
 // significado, como ocorreu na declaração das structs. 
 
strcpy ( nom, Joao_da_Silva.nome); // atribui o conteúdo do dado membro nome da struct 
 // Joao_da_Silva ao array nom. 
nres = Joao_da_Silva.residencia.numero; // atribui a nres o valor armazenado em numero, que é 
 // um dado membro da struct residencia, que por sua 
APOSTILA: LINGUAGENS DE PROGRAMAÇÃO C E C++ 
Angelo Passaro Página V.8 Segunda revisão / 2002 
 
 // vez, é um dado membro de Joao_da_Silva. 
 // Note o uso em cascata do operador de acesso. 
 
ncom = Joao_da_Silva.comercial.numero; // atribui a ncom o valor armazenado em numero, que 
 // é um dado membro da struct comercial, que por sua 
 // vez, é um dado membro de Joao_da_Silva. 
 
cep = Joao_da_Silva.comercial.cep; 
strcpy ( rcom, Joao_da_Silva.comercial.rua); 
strcpy ( rres, Joao_da_Silva.residencia.rua); 
 
strcpy ( cidres, Joao_da_Silva.residencia.cidade); 
 
 
// alteração dos dados membros da struct data 
unsigned short int a = 1998; 
unsigned char d = 13, m = 4; 
dia_formatura . dia = d; 
dia_formatura . mes = m; 
dia_formatura . ano = a; 
 
// alteração dos dados membros da struct endereço 
char r [500] = “Rua X”, cid [500] = “Mogi”; 
unsigned int n = 123; 
unsigned long int cep = 01000100; 
 
novo_end . numero = n; 
novo_end . cep = cep; 
strcpy ( novo_end . rua, r); // a função strcpy copia o conteúdo do array unidimensional 
 //de caracteres r para o membro rua 
 
 
O acesso a dados membros do tipo ponteiro é feito utilizando o operador −>. 
 
Sintaxe: 
identificador_struct −>−>−>−> identificador_ponteiro_membro 
 
Exemplos de acesso a ponteiros membro serão apresentados no capítulo que trata de ponteiros. 
 
Exercícios 
 
 
1. Considere as structures declaradas na seção V.B.1 (data, endereco e pessoa). Escreva um programa que permita 
criar um array unidimensional de structures pessoa, armazenando os dados fornecidos pelo usuário pelo teclado: 
a. declare um array unidimensional estático de 100 posições; 
APOSTILA: LINGUAGENS DE PROGRAMAÇÃO C E C++ 
Angelo Passaro Página V.9 Segunda revisão / 2002 
 
b. faça um laço para a entrada de dados via teclado (utilize cin) instruindo o usuário sobre os dados a serem 
preenchidos; 
c. terminada a entrada de dados, faça um laço sem fim no qual é pedido um índice ao usuário e, em seguida 
apresentadas as informações armazenadas na structure correspondente (use cout); 
d. implemente um teste para verificar se existem dados armazenados na structure com o índice indicado.

Continue navegando