As chaves delimitam um bloco de comandos na linguagem C e isso foi comentado no post Anatomia do programa em C.
Elas voltaram a aparecer na estrutura condicional, e é claro, delimitando um bloco de comandos tanto para o if quanto para o else.
Quando uma expressão condicional, localizada no if, é verdadeira, o bloco de comandos (que fica entre chaves) logo abaixo do if é executado. Na verdade, as chaves são obrigatórias quando o bloco de comando possui mais de uma linha de comando a ser executada. Quando existe somente uma linha de comando, as chaves passam a ser opcional. Isso, isso, isso, isso, .... Opcional!
Recorrendo novamente a divisão, temos:
001: #include <stdio.h>
002: #include <stdlib.h>
003:
004: int main(int argc, char *argv[])
005: {
006: float numerador, denominador;
007:
008: printf("Digite o numerador: ");
009: fflush(stdin);scanf("%f", &numerador);
010: printf("Digite o denominador: ");
011: fflush(stdin);scanf("%f", &denominador);
012: if(denominador != 0)
013: printf("Resultado da divisao: %f\n", numerador/denominador);
014: else
015: printf("Nao e possivel fazer divisao por zero!\n");
016: system("PAUSE");
017: return 0;
018: }
Na minha opinião, o uso das chaves auxilia a leitura do código e ainda insere um fator de segurança quando uma manutenção do código inclui mais linhas nos blocos de comando. Essa prática minimiza a ocorrência do esquecimento desenvolvedor em incluir as chaves quando ele insere as novas linhas. Esquecer as chaves quando necessárias causam grandes aborrecimentos e afinal, o esquecimento "foi sem querer, querendo!".
Eu uso sempre as chaves, exceto no else if, porque não quero ficar chorando por aí. "Pi, pi, pi, pi, pi".