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".


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.


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.


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?


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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.