Sei sulla pagina 1di 64

Aula de Java 1 Conceitos Bsicos

DAS 5316 Integrao de Sistemas Corporativos


Saulo Popov Zambiasi popov@gsigma.ufsc.br

Roteiro
Introduo Fases de um programa Java Strings Entrada e Sada Arrays Classes
Atributos Mtodos Construtores Herana

Packages Interfaces
05/12/06 2

Java
Java um ambiente de execuo completo, no apenas a linguagem de programao. Programas Java so compilados para bytecode, ou seja, um cdigo assembly independente de arquitetura; O bytecode interpretado na Java Virtual Machine (JVM); Compilao JIT (Just in Time)
A medida que a JVM detecta que um trecho de cdigo ser executado diversas vezes, este convertido, e passa a executar na CPU real.
05/12/06 3

Fases de um programa Java


Edio

package br.ufsc.gsigma; class Program { public static void ma { System.out.printl } }

Editor

Disco

05/12/06

Fases de um programa Java


Compilao
bytecode
package br.ufsc.gsigma; class Program { public static void ma { System.out.printl } } 1110010100101010101010100 1001010010101001010101001 0101101101010111001010010 1010101010100100101001010 1001010101001010110110101 0111001010010101010101010 0100101001010100101010100 1010110110101011110010100 1010101010101001001010010 1010010101010010101101101 0101111001010010101010101 0100100101001010100101010 1001010111010101111001010 0101010101010100100101001 0101001010101001010110110 1010110010100101010010101 0100101011101010111100101 0010101010101010010010100

Compilador

Bibliotecas

Disco javac <nome do arquivo>.java


05/12/06 5

Fases de um programa Java


Carregamento
1110010100101010101010100 1001010010101001010101001 0101101101010111001010010 1010101010100100101001010 1001010101001010110110101 0111001010010101010101010 0100101001010100101010100 1010110110101011110010100 1010101010101001001010010 1010010101010010101101101 0101111001010010101010101 0100100101001010100101010 1001010111010101111001010 0101010101010100100101001 0101001010101001010110110 1010110010100101010010101 0100101011101010111100101 0010101010101010010010100

JVM Carregador Verificador

...
Memria Bibliotecas

Disco

java <nome da classe>


05/12/06 6

Fases de um programa Java


Interpretao

JVM Interpretador Compilador JIT

...
Memria

05/12/06

Um Exemplo Simples
public class Exemplo { public static void main(String[] args) { System.out.println("Al, mundo"); } }

05/12/06

Um Exemplo Simples
public class Exemplo { { } } public static void main(String[] args) System.out.println("Al, mundo");
Tudo em Java deve ficar dentro de uma classe, no existem variveis ou funes globais class: Indica a declarao de uma classe.

05/12/06

Um Exemplo Simples
public class Exemplo { public static void main(String[] args) {
public static void main(String[] args)

System.out.println("Al, mundo");

Mtodo main, ponto de entrada do programa

05/12/06

10

Um Exemplo Simples
public class Exemplo { public static void main(String[] args) { System.out.println("Al, mundo"); } }
Chamada de mtodo Chamadas de mtodos so feitas seguindo a forma: <objeto>.<mtodo>(<parmetros>) Neste caso, o objeto System.out, o mtodo println, e o parmetro a string "Al, mundo"
05/12/06 11

Comentrios
Java suporta trs tipos de comentrio:
De linha (//)
System.out.println("Al, mundo"); //Que funo legal...

De bloco (/* ... */)


/* Esse comando serve pra fazer isso, depois de chamado, vai acontecer aquilo */

De documentao (/** ... */)


/** Esse mtodo calcula xyz, baseado em abc @param abc o abc usado no clculo */ public void metodoX(int abc) { ... }
05/12/06 12

Tipos de Dados
Inteiros
byte 1 byte, 128 a 127 short 2 bytes, 32.768 a 32.767 int 4 bytes, 2.147.483.648 a 2.147.483.647 long 8 bytes, 9.223.372.036.854.775.808 a 9.223.372.036.854.775.807

Ponto Flutuante
float 4 bytes, ~ 3.40282347E+38 double 8 bytes, ~ 1.79769313486231570E+308

Caracter
char 2 bytes, '\u0000' a '\uffff'

Booleano
boolean true ou false

05/12/06

13

Variveis
Todas as variveis precisam ter um tipo associado Variveis so declaradas indicando primeiramente o tipo, e em seguida o nome Pode-se opcionalmente inicializar uma varivel durante sua declarao Usar uma varivel antes de atribuir um valor a ela um erro de programao
double salario; int diasDeFolga = 30; boolean completo; completo = false;

05/12/06

14

Strings
Strings so seqncias de caracteres Java no possui um tipo especfico para representar strings, em vez disso elas so encapsuladas pela classe String At mesmo strings literais (delimitadas por aspas), so instncias da classe String Strings podem ser criadas a partir de literais, ou pela concatenao de strings com outras variveis
String str = "Al"; int x = 30; String str2 = str + " " + x; //str2 == "Al 30"
05/12/06 15

Comparando Strings
Para comparar a igualdade de duas strings deve-se usar o mtodo equals:
if ( str.equals("Al") ) ... if ( "Al".equals(str) ) ...

Caso se queira comparar strings sem levar em conta a diferena entre maisculas e minsculas, pode-se usar o mtodo equalsIgnoreCase:
if ( str. equalsIgnoreCase("Al") ) ...

NO se deve comparar strings com ==


05/12/06 16

Converso de Strings
Para converter tipos simples para string existe o mtodo valueOf(), da classe String:
String str1 = String.valueOf(23); String str2 = String.valueOf(50.75);

Para a converso de strings para tipos simples tambm existem mtodos:


int x = Integer.parseInt("42"); float f = Float.parseFloat("3.14159");

Se a converso no for possvel, uma exceo lanada.


05/12/06 17

String: Alguns Mtodos


int length()
Comprimento da string

char charAt(int index)


Retorna o caracter na posio requerida

int indexOf(String str)


Retorna a posio onde str fica na string, ou -1 se no encontrar

String substring(int beginIndex, int endIndex)


Cria uma substring, com os caracteres contidos entre beginIndex e endIndex

int compareTo(String other)


Compara com outra string, e retorna 0 se forem iguais, -1 e esta for menor que a outra, ou 1 em caso contrrio

05/12/06

18

Entrada e Sada
A leitura e a escrita de dados com o usurio feita, respectivamente, pelos objetos:
System.in System.out

Os principais mtodos de System.out so


print(...)
Imprime o contedo de uma varivel ou expresso

println(...)
Imprime o contedo de uma varivel ou expresso, e uma quebra de linha
05/12/06 19

Entrada e Sada
A partir da verso 5.0 (1.5), Java prov a classe java.util.Scanner para leitura de dados de System.in
import java.util.Scanner; public class InputTest { public static void main(String[] args) { Scanner entrada = new Scanner(System.in); System.out.print("Qual seu nome? "); String nome = entrada.nextLine(); System.out.print("Quantos anos voc tem? "); int idade = entrada.nextInt(); System.out.println("Ol, " + nome + ". Sua idade : " + idade); } }

05/12/06

20

Arrays
Arrays so estruturas de dados que armazenam uma seqncia de tamanho fixo de valores de um mesmo tipo.
int[] numeros; //array de int String[] nomes; //array de String

Assim como qualquer varivel, arrays precisam ser inicializados antes de serem usados, e isso feito:
Usando o operador new, e o tamanho desejado Fornecendo os valores diretamente
String[] nomes = new String[1024]; int[] numeros; numeros = new int[100]; char[] abc = { 'a', 'b', 'c' };

05/12/06

21

Arrays, acessando elementos


Aps a inicializao, valores podem ser atribudos a ncides do array, ou pode-se ler o valor atribudo a um ndice ndices comeam em 0 O tamanho de um array sempre pode ser obtido pelo atributo (de apenas leitura) length
nomes[0] = "Arthur"; nomes[1] = "Ford"; int tamanho = nomes.length; String ultimo = nomes[nomes.length-1];

05/12/06

22

Iterando sobre Arrays


Pode-se iterar sobre arrays de duas formas
Acessando os elementos por seus ndices
String[] array = ...; for (int i = 0; i<array.length; i++) { String str = array[i]; //Usa str }

Navegando diretamente pelos elementos


for (String str : array) { //Usa str }
05/12/06 23

Arrays multidimensionais
Java no possui uma construo explcita para arrays multidimensionais. Porm, permitido criar arrays de arrays, o que equivalente Alm disso, h uma sintaxe especial para inicializar estes arrays
int[][] tabuleiro = new int[3][3]; String dados[][][] = new String[300][10][50];

05/12/06

24

Enumeraes
Uma enumerao um tipo cujos valores possveis pertencem a um conjunto limitado, pr-definido
enum Naipe { Espadas, Ouros, Copas, Paus } Naipe n = Naipe.Espadas;

Tipos enumerados podem ser usados em switches


switch (n) { case Espadas: ... break; ... }
05/12/06 25

Enumeraes
Uma enumerao um tipo cujos valores possveis pertencem a um conjunto limitado, pr-definido
enum Naipe { Espadas, Ouros, Copas, Paus } Naipe n = Naipe.Espadas;

Tipos enumerados podem ser usados em switches enumerao, deve-se qualific-lo com o nome da
switch (n) enumerao. {

Sempre que se for usar um dos possveis valores de uma

Usa-se Naipe.Espadas, e no simplesmente Espadas case Espadas:


... Isso acontece porque mais de uma enumerao pode ter break; o valor Espadas. (Ex.: Armas.Espadas) ... }
05/12/06 26

Enumeraes
Em switches, entretando, o um tiposabe, pelo tipo da possveis Uma enumerao compilador cujos valores varivel n, a qual enum este Espadas pertence. Ento pertencem a um conjunto limitado, pr-definido no necessrio indicar o tipo.
enum Naipe { Espadas, Ouros, Copas, Paus }

Alis, estranhamente, proibido qualificar um valor de enumerao em um n = Naipe.Espadas; gera um erro Naipe switch. O compilador nestes casos

Tipos enumerados podem ser usados em switches


switch (n) { case Espadas: ... break; ... }
05/12/06 27

Classes em Java
A unidade bsica da Linguagem Java a Classe; Programas Java so compostos de objetos que interagem entre si trocando mensagens (invocando mtodos).

05/12/06

28

Exemplo
public class Motor { //Atributos private int marcha = 0; private int rotao = 0; //Construtores public Motor(int marcha) { this.marcha = marcha; } public Motor() { } //Mtodos public void sobeMarcha() { marcha++; } public void desceMarcha() { marcha--; } public int getMarcha() { return marcha; } //Outros mtodos... }

05/12/06

29

Classes
O corpo de uma classe pode conter:
Atributos; Mtodos; Construtores.

05/12/06

30

Atributos
Atributos so variveis que expressam o estado de um objeto; Como qualquer varivel, podem ser de tipos simples (int, float, boolean, etc.), um tipo referncia (classe ou interface), ou ainda um array. Ex:
private private private private int x; boolean[] b; Motor motor1; Acelervel[] ac;

Atributos podem ser inicializados em sua declarao. Ex:


private int x = 20; private Motor motor1 = new Motor(); private Acelervel[] ac = new Bicileta[5];

05/12/06

31

Atributos (cont)
Diferentemente de variveis em blocos de cdigo, atributos no inicializados explicitamente acabam recebendo um valor default;
Tipos numricos 0 boolean false Referncias null

recomendvel que atributos sejam declarados como private, garantindo assim o encapsulamento dos dados;
05/12/06 32

Mtodos
Mtodos so aes que objetos podem executar; Podem possuir parmetros, que assim como atributos podem ser de qualquer tipo simples, tipo referncia, ou array; Mtodos podem executar operaes que retornam ou no resultados. No primeiro caso seu tipo de retorno deve ser indicado, no segundo ele deve ser declarado como void.
public void fazCoisa(int param) { ... } public int calculaValor(int p1, float p2) { ... }

Mtodos podem ter o mesmo nome, desde que tenham nmero e/ou tipo de parmetros diferentes entre si.

05/12/06

33

Mtodos (cont.)
Dentro de mtodos pode-se usar a palavra chave this para fazer referncia ao objeto sobre o qual o mtodo foi chamado Mtodos que retornam algum valor devem faz-lo utilizando a palavra-chave return seguida do valor a ser retornado. Mtodos void podem tambm utilizar return para encerrar sua execuo a qualquer momento; Mtodos em geral so declarados como public, para que sejam acessveis externamente. Mas mtodos que so apenas utilizados internamente devem ser declarados como private.

05/12/06

34

Exemplo
public class Motor { public void sobeMarcha() { marcha++; } public void mudaMarcha(int marcha) { if (rotaoAdequada()) this.marcha = marcha; } public int getMarcha() { return marcha; } private boolean rotaoAdequada() { // } }

05/12/06

35

Construtores
Um construtor um tipo especial de mtodo; Um contrutor no tem tipo de retorno (nem mesmo void) e pode possuir quantos parmetros forem necessrios; Um objeto pode possuir vrios construtores.
public class Motor { private int marcha = 0; private int rotao = 0; public Motor(int marcha) { this.marcha = marcha; } public Motor() { } }

05/12/06

36

Construtores (cont.)
Se nenhum for declarado, um construtor padro, vazio, criado implicitamente; Dentro dos contrutores pode ser feita a inicializao de atributos e qualquer outra operao necessria para o objeto; O ideal que depois de contrudo, o objeto esteja pronto para operar; Objetos so criados usando a palavra chave new, seguida do nome da classe e dos parmetros do construtor.
public class Carro { private Motor motor; public Carro() {motor = new Motor(); } }

05/12/06

37

Mtodos Estticos
Mtodos estticos so mtodos que no operam em objetos double x = Math.pow(3.5, 2); int[] array = ...; Arrays.sort(array); String x = String.valueOf(2341); So definidos pela palavra chave static public static int max(int a, int b) { return a > b ? a : b; } Mdotos estticos no podem acessar atributos, pois estes so relativos a uma instncia da classe, que no existe neste contexto
38

05/12/06

Mtodo Main
O mtodo main um mtodo esttico especial, usado como ponto de partida de um programa Java; Deve ser declarado como:
public static void main(String[] args) { //comandos... }

O array de strings a lista de argumentos de linha de comando; Pode-se declarar mtodos main em qualquer classe, sendo isto muito usado para testar classes individualmente
05/12/06 39

Herana
Para declarar uma classe derivada de outra utiliza-se a palavra chave extends: Uma subclasse enxerga tudo o que no foi declarado como private na superclasse
public class Carro { private int velocidade; public int getVelocidade() { return velocidade; } } public class Formula1 extends Carro { public int calculoQualquer() { return getVelocidade() * 20; } }

05/12/06

40

Herana
Para declarar uma classe derivada de outra utiliza-se a palavra chave extends: Uma subclasse enxerga tudo o que no foi declarado Caso se tentasse na superclasse como private acessar diretamente o
atributo velocidade, ocorreria um erro public class de compilao Carro
{ private int velocidade; public int getVelocidade() { return velocidade; } } public class Formula1 extends Carro { public int calculoQualquer() { return getVelocidade() * 20; } }

05/12/06

41

Herana (cont.)
Uma subclasse pode redefinir um mtodo da superclasse, se ele no for private; Esta caracterstica chamada de polimorfismo: diferentes objetos podem ter comportamentos diferentes em relao a um mesmo mtodo. Por exemplo, a classe Carro pode calcular seu deslocamento de uma certa forma. A classe Formula1 precisa levar mais dados em considerao, como a presso aerodinmica em seus aeroflios. Ento ela reimplementa o mtodo para o clculo do deslocamento; Pode-se usar a palavra chave super para chamar mtodos e construtores da superclasse.

05/12/06

42

Exemplo super
public class Carro { ... public Carro(Motor m) { ... } public int deslocamento() { return motor.getAcerao() * 20; } } public class Formula1 extends Carro { ... public Formula1(Motor m, float inclAeroflio) { super(m); ... } public int deslocamento() { return motor.getAcerao() * inclAeroflio; } }

05/12/06

43

Protected
A palavra-chave protected um meio termo entre public e private, para a declarao de membros
Eles so, em geral, vistos como se fossem private Mas para subclasses eles so como public

Exeto em casos muito especiais, deve-se evitar o uso de protected, pois ele quebra o encapsulamento da superclasse
05/12/06 44

Vinculao Dinmica
A criao de hierarquias de classes permite que se trate, de forma abstrata, objetos de classes especializadas como se fossem de classes mais gerais Pode-se fazer:
Carro[] carros = new Carro[2]; carros[0] = new Carro(); carros[1] = new Formula1(); for (Carro c : carros) { int desloc = c.deslocamento(); System.out.println( desloc ); }

Quando um mtodo chamado, no importa o tipo declarado da varivel, a mquina virtual invoca o mtodo com base do tipo real dela

05/12/06

45

Vinculao Dinmica
A criao de hierarquias de classes permite que se trate, de formaque neste O ambiente de execuo sabe abstrata, objetos de classes especializadas como se fossem de classes mais gerais Pode-se fazer:
Carro[]

ponto, se o Carro em questo for um Formula1, ele deve chamar a verso do mtodo definida nesta classe, e no a verso carros = geral, definida na classe Carro mais new Carro[2];

carros[0] = new Carro(); carros[1] = new Formula1(); for (Carro c : carros) { int desloc = c.deslocamento(); System.out.println( desloc ); }

Quando um mtodo chamado, no importa o tipo declarado da varivel, a mquina virtual invoca o mtodo com base do tipo real dela

05/12/06

46

Coero de Objetos
Suponha que o seguinte mtodo seja adicionada classe Formula1:
String[] getPatrocinadores() {...}

Caso se queira chamar esse mtodo a partir de uma varivel do tipo Carro, preciso informar ao compilador explicitamente que aquela varivel guarda um Formula1 mesmo, e no um carro qualquer
Carro[] carros = ...; //erro de compilao String[] p = carros[0].getPatrocinadores(); //Compilador aceita Formula1 f = (Formula1) carros[0]; String[] p = f.getPatrocinadores(); 05/12/06 47

Coero de Objetos
Suponha que o seguinte mtodo seja adicionada classe Formula1:
String[] getPatrocinadores() {...}

Caso se queira chamar esse mtodo a partir de uma varivel do tipo Carro, preciso informar ao compilador explicitamente que aquela varivel guarda um Formula1 mesmo, e no um carro qualquer
Carro[] carros = ...; //erro de compilao String[] p = carros[0].getPatrocinadores(); //Compilador aceita Formula1 f = (Formula1) carros[0];

Typecast, ou coero
05/12/06

String[] p = f.getPatrocinadores(); 48

Coero de Objetos
Suponha que o seguinte mtodo seja adicionada classe Formula1:
String[] getPatrocinadores() {...}

Caso se queira chamar esse mtodo a partir de uma varivel do tipo Carro, preciso informar ao compilador explicitamente que Erro em tempo de execuo no aquela varivel guarda um Formula1 mesmo, ecaso um carro carros[0] no seja um Formula1 qualquer
Carro[] carros = ...;

ClassCastException

//erro de compilao String[] p = carros[0].getPatrocinadores(); //Compilador aceita Formula1 f = (Formula1) carros[0]; String[] p = f.getPatrocinadores(); 05/12/06 49

Checagem de tipos
Para se certificar que um objeto mesmo de um dado tipo, e assim evitar erros, pode-se checar em tempo de execuo o real tipo de um objeto. Pode-se checar explicitamente se a classe de um objeto uma dada classe, ou usar o operador instanceof.
if ( carros[0].getClass() == Formula1.class ) { Formula1 f = (Formula1)carros[0]; } if ( carros[0] instanceof Formula1 ) { Formula1 f = (Formula1)carros[0]; }
05/12/06 50

Checagem de tipos
Para se certificar que um objeto mesmo de um dado tipo, e assim evitar erros, pode-se checar em tempo de execuo o real tipo de um objeto. Pode-se checar explicitamente se a classe de um objeto uma dada classe, ou usar o operador instanceof.
if ( carros[0].getClass() == Formula1.class ) { Formula1 f = (Formula1)carros[0]; } Checa se o objeto desta classe ( carros[0] instanceof Formula1 ) if em especfico { Formula1 f = (Formula1)carros[0]; }
05/12/06 51

Checagem de tipos
Para se certificar que um objeto mesmo de um dado tipo, e assim evitar erros, pode-se checar em tempo de execuo o real tipo de um objeto. Pode-se checar explicitamente se a classe de um objeto uma dada classe, ou usar o operador instanceof.
if ( carros[0].getClass() == Formula1.class ) { Checa se o objeto f = (Formula1)carros[0]; Formula1 desta classe, ou de uma classe } descendente if ( carros[0] instanceof Formula1 ) { Formula1 f = (Formula1)carros[0]; }
05/12/06 52

Packages
Packages criam escopos para declarao de classes;
package instrumentos; public class Teclado { void tocar(); } package perifericos; public class Teclado { char ultimaTecla(); }

A package faz parte do nome da classe.


instrumentos.Teclado ti; perifericos.Teclado tp; ti.tocar(); char c = tp.ultimaTecla();
05/12/06 53

Packages
Declaraes de import permitem usar classes sem a qualificao da package. package instrumentos; public class Teclado { void tocar(); } package teste; import instrumentos.Teclado; ... Teclado t; t.tocar();

Pode-se importar todas as classes de uma package ou apenas uma classe especfica;

import nome.da.package.*; import nome.da.package.NomeDaClasse;


A package java.lang importada implicitamente.
54

05/12/06

Packages
Arquivos com declarao de package devem ter estrutura de diretrio especial. Package exemplo br.ufsc.gsigma Diretrio exempo/ br/ufsc/gsigma/

Recomenda-se que nomes de package sejam em minsculas, e sigam o nome do domnio de internet do desenvolvedor.
05/12/06 55

Packages e declaraes de classes/interfaces


Classes e interfaces podem ou no ser declaradas como pblicas;
As no declaradas como pblicas so visveis apenas por outras classes e interfaces declaradas na mesma package; As pblicas tem visibilidade externa total;
Arquivo deve ter o mesmo nome da classe/interface; Apenas uma classe/interface pblica por arquivo.
05/12/06 56

Interfaces
Permitem expressar comportamento sem se preocupar com a implementao.
interface Voador { void voar(int tempo); } class Ave implements Voador { public void voar(int tempo){...} public void comer(){...} }

class Avio implements Voador { public void voar(int tempo){...} public void abastecer(){...} } class DiscoVoador implements Voador { public void voar(int tempo){...} public void piscar(){...} } 05/12/06 57

Interfaces
Permitem expressar comportamento sem se preocupar com a implementao.
interface Voador { void voar(int tempo); } class Ave implements Voador { public void voar(int tempo){...} public void comer(){...} }

Todas as classes que implementam a interface Voador precisam prover um mtodo voar class
{

class Avio implements Voador { public void voar(int tempo){...} public void abastecer(){...} } DiscoVoador implements Voador

public void voar(int tempo){...} public void piscar(){...} } 05/12/06 58

Interfaces
Clientes usam a interface sem saber qual a classe que a implementa.
class Testador { public void testar(Voador v) { for (int i=0; i<5; i++) v.voar(10 * i); } }

Ave a = new Ave(); Avio v = new Avio(); DiscoVoador d = new DiscoVoador(); ... Testador t = new Testador(); ... t.testar(a); t.testar(v); t.testar(d);

05/12/06

59

Interfaces
Clientes usam a interface sem saber qual a classe que a implementa.
class Testador { public void testar(Voador v) { for (int i=0; i<5; i++) v.voar(10 * i); } }

O mtodo testar quer algum objeto que implemente o comportamento de um Voador, no importa qual
05/12/06

Ave a = new Ave(); Avio v = new Avio(); DiscoVoador d = new DiscoVoador(); ... Testador t = new Testador(); ... t.testar(a); t.testar(v); t.testar(d);

60

Interfaces
Uma classe pode implementar vrias interfaces
interface Animal { void comer(); void dormir(); }

interface Voador { void voar(int tempo); }

class Ave implements Voador, Animal { public void voar(int tempo){...} public void comer(){...} public void dormir(){...} } 05/12/06 61

Interfaces
Interfaces podem herdar outras interfaces
interface Animal { void comer(); void dormir(); } interface Voador { void voar(int tempo); }

interface Mamfero extends Animal { void mamar(); }

interface AnimalVoador extends Animal, Voador { }

05/12/06

62

Continua...

Instalao de Ambinte de Programao


Mquina virtual
Java da Sun - http://java.sun.com/
Java SE - http://java.sun.com/j2se/1.5.0/download.jsp
JDK 5.0 (Java Development Kit)

Ambiente de Desenvolvimento
Eclipse - http://www.eclipse.org/
Eclipse SDK 3.1 (ou superior)

Netbeans - http://www.netbeans.org/
Netbeans IDE 5.0 (ou superior)

05/12/06

Carlos E. Gesser GSIGMA / DAS / UFSC