Eu sei um pouco de C e agora estou dando uma olhada no C ++. Estou acostumado a matrizes de caracteres para lidar com seqüências de caracteres C, mas enquanto eu observo o código C ++, vejo que existem exemplos usando o tipo de sequência de caracteres e as matrizes de caracteres:
#include <iostream>
#include <string>
using namespace std;
int main () {
string mystr;
cout << "What's your name? ";
getline (cin, mystr);
cout << "Hello " << mystr << ".\n";
cout << "What is your favorite team? ";
getline (cin, mystr);
cout << "I like " << mystr << " too!\n";
return 0;
}
e
#include <iostream>
using namespace std;
int main () {
char name[256], title[256];
cout << "Enter your name: ";
cin.getline (name,256);
cout << "Enter your favourite movie: ";
cin.getline (title,256);
cout << name << "'s favourite movie is " << title;
return 0;
}
(os dois exemplos de http://www.cplusplus.com )
Suponho que essa seja uma pergunta amplamente respondida (óbvia?), Mas seria bom se alguém pudesse me dizer qual é exatamente a diferença entre essas duas maneiras de lidar com seqüências de caracteres em C ++ (desempenho, integração de API, a maneira como cada uma delas é Melhor, ...).
Obrigado.
Respostas:
Uma matriz de caracteres é exatamente isso - uma matriz de caracteres:
Uma string é uma classe que contém uma matriz de caracteres, mas a gerencia automaticamente para você. A maioria das implementações de cadeia de caracteres possui uma matriz interna de 16 caracteres (portanto, cadeias curtas não fragmentam a pilha) e usam a pilha para cadeias mais longas.
Você pode acessar o array de caracteres de uma string assim:
As seqüências de caracteres C ++ podem conter caracteres \ 0 incorporados, saber seu tamanho sem contar, são mais rápidas que matrizes de caracteres alocadas em heap para textos curtos e protegem você de excedentes de buffer. Além disso, são mais legíveis e fáceis de usar.
No entanto, as seqüências de caracteres C ++ não são (muito) adequadas para uso através dos limites da DLL, porque isso exigiria que qualquer usuário dessa função DLL certificasse-se de que ele está usando exatamente o mesmo compilador e implementação de tempo de execução do C ++, para que não arrisque que sua classe de string se comporte de maneira diferente.
Normalmente, uma classe de string também liberaria sua memória heap no heap de chamada, portanto, somente poderá liberar memória novamente se você estiver usando uma versão compartilhada (.dll ou .so) do tempo de execução.
Em resumo: use seqüências de caracteres C ++ em todas as suas funções e métodos internos. Se você escrever uma .dll ou .so, use seqüências de caracteres C em suas funções públicas (dll / tão expostas).
fonte
Arkaitz está correto, que
string
é um tipo gerenciado. O que isso significa para você é que você nunca precisa se preocupar com a duração da string, nem precisa liberar ou realocar a memória da string.Por outro lado, a
char[]
notação no caso acima restringiu o buffer de caracteres a exatamente 256 caracteres. Se você tentou gravar mais de 256 caracteres nesse buffer, na melhor das hipóteses, substituirá a outra memória que o seu programa "possui". Na pior das hipóteses, você tentará sobrescrever a memória que você não possui, e seu sistema operacional matará seu programa no local.Bottom line? Strings são muito mais amigáveis para programadores, char [] s são muito mais eficientes para o computador.
fonte
Bem, o tipo de seqüência de caracteres é uma classe completamente gerenciada para seqüências de caracteres, enquanto char [] ainda é o que era em C, uma matriz de bytes que representa uma sequência de caracteres para você.
Em termos de API e biblioteca padrão, tudo é implementado em termos de strings e não char [], mas ainda existem muitas funções da libc que recebem char [], então você pode precisar usá-lo para elas, além do que eu faria sempre use std :: string.
Em termos de eficiência, é claro, um buffer bruto de memória não gerenciada quase sempre será mais rápido para muitas coisas, mas leve em consideração a comparação de strings, por exemplo, std :: string sempre tem o tamanho para checá-lo primeiro, enquanto char [] você precisa comparar caractere por caractere.
fonte
Pessoalmente, não vejo nenhuma razão pela qual alguém queira usar char * ou char [], exceto pela compatibilidade com o código antigo. std :: string não é mais lento do que usar uma c-string, exceto que ele manipulará a realocação para você. Você pode definir seu tamanho ao criá-lo e, assim, evitar a realocação, se desejar. O operador de indexação ([]) fornece acesso em tempo constante (e em todos os sentidos da palavra é exatamente a mesma coisa que usar um indexador de c-string). Usar o método at também oferece segurança verificada nos limites, algo que você não obtém com c-strings, a menos que você o escreva. Seu compilador geralmente otimiza o uso do indexador no modo de liberação. É fácil mexer com c-strings; coisas como excluir x excluir [], segurança de exceção e até mesmo como realocar uma string c.
E quando você tiver que lidar com conceitos avançados, como ter strings COW e não COW para MT, etc, precisará de std :: string.
Se você está preocupado com cópias, contanto que você use referências e referências constantes sempre que puder, você não terá nenhuma sobrecarga devido a cópias, e é a mesma coisa que você faria com o c-string.
fonte
As strings têm funções auxiliares e gerenciam matrizes de char automaticamente. Você pode concatenar seqüências de caracteres; para uma matriz de caracteres, você precisará copiá-la para uma nova matriz; as seqüências de caracteres podem alterar seu comprimento no tempo de execução. Um array de caracteres é mais difícil de gerenciar do que uma string e certas funções podem aceitar apenas uma string como entrada, exigindo a conversão da matriz em uma string. É melhor usar seqüências de caracteres, elas foram feitas para que você não precise usar matrizes. Se as matrizes fossem objetivamente melhores, não teríamos seqüências de caracteres.
fonte
Pense em (char *) como string.begin (). A diferença essencial é que (char *) é um iterador e std :: string é um contêiner. Se você seguir as strings básicas, um (char *) fornecerá o que std :: string :: iterator faz. Você pode usar (char *) quando quiser o benefício de um iterador e também a compatibilidade com C, mas essa é a exceção e não a regra. Como sempre, tenha cuidado com a invalidação do iterador. Quando as pessoas dizem (char *) não é seguro, é isso que elas querem dizer. É tão seguro quanto qualquer outro iterador C ++.
fonte
Uma das diferenças é a terminação nula (\ 0).
Em C e C ++, char * ou char [] levará um ponteiro para um único char como parâmetro e acompanhará a memória até que um valor de memória 0 seja atingido (geralmente chamado de terminador nulo).
As strings C ++ podem conter caracteres \ 0 incorporados, saber seu tamanho sem contar.
Resultado:
fonte