AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / coding / Perguntas / 76930988
Accepted
John Peters
John Peters
Asked: 2023-08-19 00:10:34 +0800 CST2023-08-19 00:10:34 +0800 CST 2023-08-19 00:10:34 +0800 CST

Por que uma string C nem sempre é equivalente a uma matriz de caracteres?

  • 772

Dado que uma string C é uma matriz de caracteres terminada em nulo:

const char str1[] = {"abc"};
const char str2[] = {'a', 'b', 'c', '\0'};
const char str3[] = {97, 98, 99, '\0'};

são os mesmos.

Então, por que é possível gerar uma matriz de strings como esta:

const char * str_arr[] = {"abc", "ABCD"};
const char * str_arr[] = { str1, str2, str3 };

mas não assim? :

const char * str_arr[] = { {'a', 'b', 'c', '\0'}, {'A', 'B', 'C', 'D', '\0'} };
fatal error: excess elements in scalar initializer
arrays
  • 2 2 respostas
  • 69 Views

2 respostas

  • Voted
  1. Best Answer
    Eric Postpischil
    2023-08-19T00:51:16+08:002023-08-19T00:51:16+08:00
    const char str1[] = {"abc"};
    const char str2[] = {'a', 'b', 'c', '\0'};
    const char str3[] = {97, 98, 99, '\0'};
    

    Eles funcionam devido às regras em C 2018 6.7.9 sobre como os inicializadores são processados:

    • Em const char str1[] = {"abc"};, uma string literal é fornecida para inicializar uma matriz de const char. 6.7.9 14 diz “Uma matriz de tipo de caractere pode ser inicializada por uma cadeia de caracteres literal ou uma cadeia de caracteres UTF–8 literal, opcionalmente entre colchetes. Bytes sucessivos da string literal (incluindo o caractere nulo de terminação se houver espaço ou se a matriz for de tamanho desconhecido) inicializam os elementos da matriz.”
    • Em const char str2[] = {'a', 'b', 'c', '\0'};, uma lista de intvalores (as constantes de caracteres têm o tipo int) é fornecida para inicializar um array. 6.7.9 17 nos diz que eles são usados ​​para inicializar os subobjetos do array (seus elementos) em ordem.
    const char * str_arr[] = {"abc", "ABCD"};
    const char * str_arr[] = { str1, str2, str3 };
    

    Para estes:

    • Em const char * str_arr[] = {"abc", "ABCD"};, uma lista de strings literais é usada para inicializar uma matriz de ponteiros. Observe que esta não é uma string literal entre colchetes; são dois literais de cadeia de caracteres, portanto, não correspondem à regra acima. Não há nenhuma regra especial para strings literais sendo usadas para inicializar uma matriz de ponteiros em vez de uma matriz de tipo de caractere, portanto, ela é tratada usando outras regras de C e as duas strings literais inicializam dois elementos da matriz. Uma string literal designa uma matriz de caracteres. 6.3.2.1 3 diz que quando um array não é o operando de sizeof, o operando de unary&, ou uma string literal usada para inicializar uma matriz, ela é convertida em um ponteiro para seu primeiro elemento. Portanto, cada uma dessas duas matrizes, aquelas designadas pelas strings literais, é convertida em um ponteiro para seu primeiro elemento, e esses ponteiros se tornam os valores iniciais de str_arr.
    • In const char * str_arr[] = { str1, str2, str3 };, str1, str2e str3são matrizes. Como logo acima, eles são convertidos automaticamente em ponteiros para seus primeiros elementos, e esses ponteiros são usados ​​para inicializar str_arr.
    const char * str_arr[] = { {'a', 'b', 'c', '\0'}, {'A', 'B', 'C', 'D', '\0'} };
    

    Para isso, cada elemento de str_arré um const char *, e o inicializador oferecido para ele é {'a', 'b', 'c', '\0'}. Não há nenhuma regra em C que a const char *possa ser inicializada com uma lista de intvalores entre chaves. Quando {'a', 'b', 'c', '\0'}aparece nos inicializadores, não tem nenhum significado especial como array. É apenas uma lista de valores. Como essa lista de valores é processada depende do contexto da inicialização. Se houvesse um array para preencher, os valores na lista poderiam ser usados ​​para preencher os elementos do array. Mas não há array e não há regra que diga que essa lista de valores é transformada em array e um ponteiro para esse array é feito.

    • 3
  2. Siguza
    2023-08-19T00:21:16+08:002023-08-19T00:21:16+08:00

    Você realmente pode, se você os lançar para const char []:

    const char * str_arr[] = { (const char []){'a', 'b', 'c', '\0'}, (const char []){'A', 'B', 'C', 'D', '\0'} };
    

    Você não pode inicializar um tipo de const char *com uma matriz de chars (porque onde está o ponteiro?), mas pode inicializar um tipo de const char[]com isso e fazer com que ele se transforme em const char *.

    • 0

relate perguntas

  • PowerShell: Como transformar valores de matriz hastable como este?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    destaque o código em HTML usando <font color="#xxx">

    • 2 respostas
  • Marko Smith

    Por que a resolução de sobrecarga prefere std::nullptr_t a uma classe ao passar {}?

    • 1 respostas
  • Marko Smith

    Você pode usar uma lista de inicialização com chaves como argumento de modelo (padrão)?

    • 2 respostas
  • Marko Smith

    Por que as compreensões de lista criam uma função internamente?

    • 1 respostas
  • Marko Smith

    Estou tentando fazer o jogo pacman usando apenas o módulo Turtle Random e Math

    • 1 respostas
  • Marko Smith

    java.lang.NoSuchMethodError: 'void org.openqa.selenium.remote.http.ClientConfig.<init>(java.net.URI, java.time.Duration, java.time.Duratio

    • 3 respostas
  • Marko Smith

    Por que 'char -> int' é promoção, mas 'char -> short' é conversão (mas não promoção)?

    • 4 respostas
  • Marko Smith

    Por que o construtor de uma variável global não é chamado em uma biblioteca?

    • 1 respostas
  • Marko Smith

    Comportamento inconsistente de std::common_reference_with em tuplas. Qual é correto?

    • 1 respostas
  • Marko Smith

    Somente operações bit a bit para std::byte em C++ 17?

    • 1 respostas
  • Martin Hope
    fbrereto Por que a resolução de sobrecarga prefere std::nullptr_t a uma classe ao passar {}? 2023-12-21 00:31:04 +0800 CST
  • Martin Hope
    比尔盖子 Você pode usar uma lista de inicialização com chaves como argumento de modelo (padrão)? 2023-12-17 10:02:06 +0800 CST
  • Martin Hope
    Amir reza Riahi Por que as compreensões de lista criam uma função internamente? 2023-11-16 20:53:19 +0800 CST
  • Martin Hope
    Michael A formato fmt %H:%M:%S sem decimais 2023-11-11 01:13:05 +0800 CST
  • Martin Hope
    God I Hate Python std::views::filter do C++20 não filtrando a visualização corretamente 2023-08-27 18:40:35 +0800 CST
  • Martin Hope
    LiDa Cute Por que 'char -> int' é promoção, mas 'char -> short' é conversão (mas não promoção)? 2023-08-24 20:46:59 +0800 CST
  • Martin Hope
    jabaa Por que o construtor de uma variável global não é chamado em uma biblioteca? 2023-08-18 07:15:20 +0800 CST
  • Martin Hope
    Panagiotis Syskakis Comportamento inconsistente de std::common_reference_with em tuplas. Qual é correto? 2023-08-17 21:24:06 +0800 CST
  • Martin Hope
    Alex Guteniev Por que os compiladores perdem a vetorização aqui? 2023-08-17 18:58:07 +0800 CST
  • Martin Hope
    wimalopaan Somente operações bit a bit para std::byte em C++ 17? 2023-08-17 17:13:58 +0800 CST

Hot tag

python javascript c++ c# java typescript sql reactjs html

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve