C

Lista Encadeada

Uma lista encadeada é um modelo conceitual para a representação de uma sequência de informações armazenadas de forma dinâmica na memória de um computador. Cada informação é armazenada em uma célula ou nó da lista: o primeiro elemento na primeira célula, o segundo na segunda e assim por diante. A estrutura de uma lista encadeada é geralmente representada por uma caixa divida em dois espaços, um para armazenar a informação e o outro para guardar o endereço da próxima caixa.

Existem vários tipos de listas encadeadas disponíveis na literatura, só para citar:

  • Lista encadeada
  • Lista duplamente encadeada
  • Lista circular
  • Pilha
  • Fila
  • Árvores Binárias

A principal diferença entre essas estruturas são as regras e restrições de acesso que elas possuem. Logo, o programador deve analisar as características de cada uma e ver qual se adapta melhor na resolução do problema. Eu poderia apontar aqui um conjunto vasto de vantagens e desvantagens de cada uma, mas isso seria uma discussão um pouco extensa. Vou deixar essa discussão para os próximos posts. Se desejar observar um exemplo de implementação de algumas dessas estruturas, consulte este repositório de código com implementações em C.

Programa que Identifica Palindromes

/* Data: 24/02/2011
 * Programador: Valberto Carneiro
 * Objetivo: Faça um programa que leia uma string do teclado e diga se ela é
   palíndrome. Uma string é palíndrome quando pode ser lida tanto
   de trás pra frente quanto de frente para trás e possui exatamente
   a mesma seqüência de caracteres. Ex.: ASA, SUBI NO ONIBUS.
   Desconsidere os espaços.
   Defina uma função chamada Palindrome que receba uma string como
   parâmetro e retorne um boolean no seu programa.
   Dica: Use a função do exercício 1.
 */

#include<stdio.h>
const int FALSE = 0;
const int TRUE = -1;

int is_palindrome(char *texto) {
  int palindrome = TRUE, tamanho = strlen(texto), y = 0, x = 0;

  //elimina brancos
  while(x < tamanho) {
    if(texto[x] == ' ') for(y=x; y < tamanho; y++) texto[y] = texto[y+1];
    x++;
  }

  tamanho = strlen(texto);

  //compara os caracteres
  for(x = 0; x < tamanho ; x++) {
    //printf("%c = %c\n", texto[x], texto[tamanho-1-x]);
    if (texto[x] != texto[tamanho-1-x]) {
      palindrome = FALSE;
      break;
    }
  }
  return palindrome;
}
int main(){
  char texto[100];
  printf("Escreva uma string para sabermos se ela é palindrome: ");
  gets(texto);
  printf("Resultado: %s", is_palindrome(texto) == FALSE ? "nao" : "sim");
  getch();
}

Strings em C

Introdução

A línguagem C é considerada de nível médio, ou seja, uma linguagem de programação que se aproxima da linguagem humana, mas que também utiliza explicitamente características de “linguagem de máquina”. As Strings em C não trazem abstrações e facilidades que escondem alguns detalhes como:

  • contagem de caracteres
  • tamanho da variável que armazenará a string
  • caractere de terminação entre outros.

Como é uma string em C?

“Uma string de caracteres em C é apenas uma matriz de caracteres” [1], ou seja, para se conseguir armazenar uma string em C, é preciso declarar um array de char com o tamanho máximo que a sua string pode ter.

char variavel[100];

É importante saber que na string acima, você pode armazenar até 99 caracteres. Mas por que? Em C, um dos espaços string guarda o caractere de terminação que serve também para contar o tamanho da string na matriz de caracteres. “As operações de I/O de strings de caracteres (gets, puts, etc.) são implementadas em <stdio.h> e um conjunto de funções de manipulação de strings de caracteres bastante simples é implementado em <string.h>.” [1]

Ler strings em C

Há mais de uma maneira de se ler strings em C, uma delas é utilizando o comando scanf. Veja algumas características:

  • Lê até o primeiro espaço em branco – Você pode digitar uma frase inteira, porém o que a variável armazenará será a primeira sequência de caracteres até o espaço em branco. Use o scanf quando necessitar armazenar strings sem espaços como: logins, senhas, e-mails, urls etc. Abaixo há um exemplo comum de utilização:
  • Não precisa indicar o “&” antes da variável, como se faz quando queremos ler inteiros, por exemplo,  pois o vetor de caracteres já é um endereço de memória que aponta para a primeira posição. Veja o exemplo. [4].
  • Aceita vários tipos de parâmetros para formatar, delimitar ou restringir a leitura de determinados caracteres.
scanf("%s", texto); //lê uma string
scanf("%d", &valor); //lê um inteiro
scanf("%[A-Z]s", frase); //lê apenas caracteres entre A a Z. Para no primeiro caractere fora desse intervalo
scanf("%[^\n]s", frase); //lê qualquer caractere inclusive espaços (igual ao comando gets();)
scanf("%50[^\n]s", frase);// lê apenas 50 caracteres

strcpy

é usado sempre que se deseja copiar uma string em outra. Esse comando é necessário, pois como as duas strings são arrays de caracteres, cada caractere de uma string é copiada para a outra string. Uma por uma. Trabalho árduo.

strcpy(destino, origem);

strcmp

é usado quando se deseja comparar strings. Aqui, o valor de retorno pode ser:

  • zero (0): caso as duas strings sejam iguais
  • negativo (-1): caso a primeira string seja menor que a segunda
  • positivo (1): caso a primeira string seja maior que a segunda

Esse valor usado na comparação para determinação de maior menor ou igual é o código ASCII do caractere comparado. Esse comando varre toda a string comparando caractere  por caractere.

#include
#include

int main() {
  char s1[100],s2[100];
  gets(s1);
  gets(s2);
  if (strcmp(s1,s2)==0)
    printf("igual\n");
  else if (strcmp(s1,s2)<0)
    printf("s1 menor que s2\n");
  else
    printf("s1 maior que s2\n");
  return 0;
}

strlen

esta função retorna o tamanho da sua string. Ele identifica o tamanho da sua string assim que encontra o caractere de terminação, o “contra-barra zero”.

char nome[] = "Maria da Silva";
int s = strlen (nome);
// s conterá o valor 14

strcat

concatena duas strings, adicionando o conteúdo da segunda ao final da primeira, além do terminador (). Note que a primeira string deve ter espaço suficiente para conter a segunda, para que não ocorra um “estouro de buffer” [2].

char nome[50] = "Maria";
char sobrenome[] = " da Silva";
strcat (nome, sobrenome);
// agora nome contém "Maria da Silva"

Exercícios

[3] possui uma excelente lista de exercícios.

Referências

[1] Marshall Brain. String de Caracteres. <http://informatica.hsw.uol.com.br/programacao-em-c35.htm&gt;

[2] ___. Programar em C/Strings. <http://pt.wikibooks.org/wiki/Programar_em_C/Strings&gt;

[3] Unicamp. Algoritmos e Programação de Computadores. <http://www.ic.unicamp.br/~rodolfo/Cursos/mc102/1s2003/exercicios4.html&gt;

[4] Islene Calciolari Garcia. Manipulação de Strings.  <http://www.ic.unicamp.br/~islene/mc102/aula17/aula17.pdf&gt;

Estrutura de um programa em C com loop de reexecução

Revendo alguns conceitos de C e pesquisando nuns sites por aí, encontrei um exeplo que acredito ser pático pra quem quer fazer rapidamente um programa em C.

Aqui é uma estrutura básica, copie e cole no seu arquivo.c, edite da forma como desejar e compile. Pronto, vc terá um programa que só para quando vc quer. 😀

#include<stdio.h>
#include<conio.h>

void main(void) {
  short int rodando;
  do {
    // DIGITE SEU CÓDIGO AQUI.
    printf("\nDigite 1 para manter o programa rodando. ");
    scanf("%d", &amp;rodando);
  } while(rodando==1);
}