Quais são as especificidades da definição de uma string em C?

10

Devo responder a uma pergunta de lição de casa para uma das minhas aulas. Especificamente, devo dizer se certas matrizes em C são consideradas cadeias ou não. Com base neste artigo ( https://www.geeksforgeeks.org/strings-in-c-2/ ), eu sei que strings são uma matriz de caracteres com o terminador nulo no final.

Meu hangup principal é uma parte da pergunta que faz uma matriz que se parece com isso:

char c1[] = { 'C', 'S', '\0', '3', '2', '4', '\0' };

Obviamente, essa é uma matriz de caracteres com um caractere final nulo no final. No entanto, ele ainda é considerado uma sequência, pois também possui um caractere final nulo no meio? Como isso afetará a string?

EDIT: Com base nos comentários, forneço a redação real da pergunta:

"Quais das matrizes a seguir podem ser consideradas" strings "para fins de usá-las como argumentos para funções strcpy (), strncpy (), strcmp (), strncmp () e strings similares (indicar todas as opções aplicáveis)?"

EDIT: Enviei um e-mail ao meu professor, pois a pergunta parecia ambígua (como várias pessoas apontaram). Se alguém estiver curioso, ele me disse: "Sim, é uma string. A chave é que existe um caractere nulo. Mas é claro que isso afetará qualquer operação de string; a string termina no caractere nulo".

quango
fonte
4
Você pode dizer que é a string "CS"com alguns bytes de lixo anexados (nesse caso, o caractere NUL final é irrelevante). Mas não é uma string "como um todo". - No entanto, alimentá-lo com strcpyetc. não fará o seu PC explodir porque essas funções "verão" apenas a "CS"parte.
Hagen von Eitzen em
2
c1 pode absolutamente ser usado como argumento para strcmp(). Se ele pode ser usado como argumento para modificar funções de string depende de fatores adicionais que não são fornecidos.
EOF
2
O conteúdo de c1é mutável, por isso não vejo por que não seria um argumento de destino válido strcpyou similar, a menos que não fosse grande o suficiente para acomodar a cadeia de origem. Isso não faria com que não fosse uma sequência, apenas não adequada para um determinado objetivo.
John Bollinger
11
No geral, eu concordo que a pergunta é ambígua. A expressão c1satisfaria os requisitos básicos para argumentos de cadeia de caracteres para todas as funções de cadeia (estreita) da biblioteca padrão, incluindo todas as nomeadas especificamente, mas o comportamento pode não ser o que o chamador espera ou deseja (mesmo ignorando comportamentos indefinidos que podem ser desencadeados).
John Bollinger
11
Observe que o tipo não precisa ser char. Qualquer tipo de caractere serve .
chux - Restabelece Monica

Respostas:

8

c1é na maior parte [1] equivalente a &c1[0], que está segurando uma string "CS",.

Há uma segunda corda à espreita lá, "324", a partir de &c1[3]-, mas contanto que você acessar c1como c1, a string "CS"é todas as funções strcpy()et al. veria.


[1]: c1é uma matriz, &c1[0]é um ponteiro.

DevSolar
fonte
Então, é apropriado usar c1como a string de destino em um strcpy()comando? A questão é ambígua - na melhor das hipóteses.
Andrew Henle
11
Claro que você pode usar c1como argumento para strcpy(). É uma corda perfeitamente comum em todos os sentidos. Sequências comuns geralmente contêm lixo restante após seus terminadores. O fato de esse lixo ser codificado no programa dá a impressão de que o autor pretende usar de c1maneira não-string, mas isso não fazia parte da questão.
Lee Daniel Crocker
" c1é equivalente a &c1[0]" engana. c1é uma matriz. &c1[0]é um ponteiro.
chux - Restabelece Monica
2

Se você deseja conhecer as especificidades da definição de uma string em C, acesse a fonte.

Do padrão C90 :

7 Biblioteca

7.1 Introdução

7.1.1 Definições de termos
Uma string é uma sequência contígua de caracteres terminados por e incluindo o primeiro caractere nulo. Um "ponteiro para" uma seqüência de caracteres é um ponteiro para seu caractere inicial (com o endereço mais baixo). O "comprimento" de uma sequência é o número de caracteres que precede o caractere nulo e seu "valor" é a sequência dos valores dos caracteres contidos, em ordem.

(Não houve alterações relevantes nos padrões posteriores.)

Portanto, c1contém duas seqüências consecutivas, "CS" e "324", mas não é uma sequência em si.

Se passarmos uma matriz para uma função, ela decai para um ponteiro para o seu primeiro elemento, assim +c1aponta para uma string (a primeira), que é boa o suficiente para qualquer função que espera um ponteiro para a string. Não aponta para uma string "CS \ 0324", mas provavelmente é boa o suficiente para a pergunta dos instrutores, que é ambígua.

Desduplicador
fonte
4
Eu diria que, mesmo por essa definição, c1 é claramente a string "CS". Período. O fato de que ele pode conter bytes diferentes de zero depois que o terminador é irrelevante - muitas strings serão assim durante a vida útil.
Lee Daniel Crocker
+c1aponta para uma sequência, porque c1começa com uma sequência. Isso de nenhuma maneira, forma ou forma forma c1uma corda.
Deduplicator
2
É o endereço de uma seção da memória que contém alguns caracteres terminados por um byte zero. Se printf () funcionasse bem com um% s, daria um número perfeitamente bom passado para strlen (), funcionaria se passado para strcpy (), etc. Soa como uma string para mim.
Lee Daniel Crocker
Claro. Mas matrizes certamente podem ser cadeias de caracteres.
Lee Daniel Crocker
0

Adicionando à resposta do @ DevSolar, algo que eu descobri depois de brincar com a string especificada, se fosse:

char c1[] = { 'C', 'S', '\\0', '3', '2', '4', '\\0' };

Se você produzir essa string, obterá CS03240e o tamanho dessa string será 7. No meu entendimento, \\0é usado para denotar o caractere nulo ( ou seja \0 ). Se você fizer:

printf("\0");

Você não vê nada no log de saída, mas se o fizer:

printf("\\0");

Você vê um \0, algo que é esperado porque, para gerar caracteres especiais, como barras invertidas ou aspas, é necessário usar um \junto com eles.

Algo que me intriga é a saída CS03240e o tamanho 7. É comum entender que o tamanho de uma string é o número de caracteres nela mais um (para o caractere nulo). Além disso, o tamanho é 7, mesmo para a sequência char c1[] = { 'C', 'S', '\0', '3', '2', '4', '\0' };,.

Então, talvez um acompanhamento para esta pergunta, o que está acontecendo aqui?

rasengan__
fonte
11
'\\0'não é um caractere nulo . É uma constante de vários caracteres. Ele tem um valor definido de implementação certamente fora da faixa de char. c1[]não é uma string, pois não possui um caractere nulo . "você produz esta string" provavelmente resulta em um comportamento indefinido .
chux - Restabelece Monica
Eu não te entendi exatamente, mas procurei constantes com vários caracteres. Se c1 [] não é uma sequência porque não possui um caractere nulo no final, por que o tamanho está saindo como 7 no caso inicial, conforme publicado pelo OP?
rasengan__
char c1[] = { 'C', 'S', '\0', '3', '2', '4', '\0' };é tamanho 7 porque é inicializado com 7 valores. Seu tamanho não tem nada a ver com cordas . char c1[] = { 1, 2, 3, 4, 5, 6, 7 };ainda faria com que fosse tamanho 7.
chux - Restabelece Monica
Quanto ao array c1contém uma picada? Essa é uma questão separada. Veja também
chux - Reinstate Monica