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 / user-30189047

ALICEZzz's questions

Martin Hope
ALICEZzz
Asked: 2025-04-29 23:14:59 +0800 CST

Como funciona o escopo do bloco? Como o padrão explica isso?

  • 8

Por exemplo, temos o seguinte código:

#include <stdio.h>
int main(void)
{
    int n = 4;
    {
        n++;
    }
    printf("%d\n",n);
    return 0;
}

Como o bloco interno vê a variável n? Como o padrão da linguagem C explica isso? Há algum tempo venho procurando uma resposta para essa pergunta. Na minha opinião, a resposta é a seguinte: em C17, temos (6.8 #3):

Um bloco permite que um conjunto de declarações e instruções seja agrupado em uma unidade sintática. Os inicializadores de objetos com duração de armazenamento automática e os declaradores de array de comprimento variável de identificadores comuns com escopo de bloco são avaliados e os valores são armazenados nos objetos (incluindo o armazenamento de um valor indeterminado em objetos sem um inicializador) cada vez que a declaração é alcançada, na ordem de execução, como se fosse uma instrução, e dentro de cada declaração na ordem em que os declaradores aparecem.

Se você não considerar os inicializadores, descobrirá que um bloco é composto apenas de algumas instruções. Usamos um bloco para avaliar todos esses operadores como uma unidade sintática. Em outras palavras, se você remover os caracteres {} do bloco, esses serão os mesmos operadores e o resultado será exatamente o mesmo, mas esses operadores não serão avaliados em uma unidade sintática:

#include <stdio.h>
int main(void)
{
    int n = 4;
    
        n++; // same effect but without {}
    
    printf("%d\n",n);
    return 0;
}

Também temos (6.2.1 # 4):

Se o declarador ou especificador de tipo que declara o identificador aparecer dentro de um bloco ou dentro da lista de declarações de parâmetros em uma definição de função, o identificador terá escopo de bloco, que termina no final do bloco associado.

A partir disso entendemos que n tem um escopo de bloco.

Se combinarmos tudo isso, descobrimos que n é incrementado como se o operador de incremento nunca tivesse aparecido no bloco interno.

Esta resposta está correta? Se não, explique o porquê. E cite um parágrafo do padrão da linguagem C.

c
  • 3 respostas
  • 100 Views
Martin Hope
ALICEZzz
Asked: 2025-04-11 13:13:51 +0800 CST

Como chamamos isso de "int * nome[4]" usando esta frase "lista de tipos de declaradores derivados de T"

  • 8

No C17 temos isto (6.7.6.2 #3):

Se, na declaração “ T D1”, D1tiver uma das formas:

 D [ lista de qualificadores de tipo opt expressão de atribuição opt ]
 D [ lista de qualificadores de tipo opt expressão de atribuição ]
 D [ lista de qualificadores de tipo static expressão de atribuição ]
 D [ lista de qualificadores de tipo opt ]

e o tipo especificado para ident na declaração “ T D” é “ derived-declarator-type-list T ”, então o tipo especificado para ident é “ derived-declarator-type-list array of T ”. 144) (Veja 6.7.6.3 para o significado dos qualificadores de tipo opcionais e da palavra-chave static.)

Derivado não é float, ou int, ou char, é "matriz de", ou "ponteiro para".

Por exemplo, temos int name [2][3], aqui Testá int, e D1é A[2][3], com a forma D[3]onde Dé A[2], então T Dé int A[2], ou "matriz de 2 int". Então o tipo declarado de Aé "matriz de 2 matriz de 3 int".

Mas e quanto a int * name[4]?

Aqui, a " lista de tipos de declaradores derivados T " será int * name. E, ao que parece, o " array de lista de tipos de declaradores derivados de T " será um ponteiro para um array de 4 elementos?

No fim das contas, isso está errado, porque int *name[4]é um array de 4 ponteiros. Por favor, me explique.

arrays
  • 2 respostas
  • 130 Views
Martin Hope
ALICEZzz
Asked: 2025-04-07 06:15:17 +0800 CST

Por que podemos usar arrays de arrays em C?

  • 7

Por que podemos usar arrays de arrays em C? Essa foi a minha pergunta quando abri a linguagem C padrão (C17).

Encontrei algo interessante (6.2.5 "Tipos" /20):

Qualquer número de tipos derivados pode ser construído a partir dos tipos objeto e função, como segue: — Um tipo array descreve um conjunto não vazio de objetos alocados contiguamente com um tipo de objeto membro específico, chamado de tipo elemento. O tipo elemento deve ser completo sempre que o tipo array for especificado. Tipos array são caracterizados por seu tipo elemento e pelo número de elementos no array. Um tipo array é dito ser derivado de seu tipo elemento, e se seu tipo elemento for T, o tipo array é algumas vezes chamado de "array de T". A construção de um tipo array a partir de um tipo elemento é chamada de "derivação de tipo array".

Em C, temos tipos de objeto, tipos de função e tipos incompletos. Os elementos de um array têm um tipo de objeto, não um tipo derivado, e pensei: "E agora?". E então encontrei isto (6.7.6.2/1 e 6.7.6.2/3):

Além dos qualificadores de tipo opcionais e da palavra-chave static, [ e ] podem delimitar uma expressão ou*. Se delimitarem uma expressão (que especifica o tamanho de um array), a expressão deverá ser do tipo inteiro. Se a expressão for uma expressão constante, deverá ter um valor maior que zero. O tipo de elemento não deverá ser um tipo incompleto ou de função. Os qualificadores de tipo opcionais e a palavra-chave static deverão aparecer apenas na declaração de um parâmetro de função com um tipo array e, mesmo assim, apenas na derivação de tipo de array mais externa.

  • Se, na declaração “T D1”, D1 tiver uma das formas: D [type-qualifier-listopt assignment-expressionopt] D [type-qualifier-listopt assignment-expression] D [type-qualifier-list static assignment-expression] D [type-qualifier-listopt] e o tipo especificado para ident na declaração “TD” for “derived-declarator-type-list T”, então o tipo especificado para ident será “derived-declarator-type-list array of T”.144) (Consulte 6.7.6.3 para o significado dos qualificadores de tipo opcionais e da palavra-chave static.)

Em 6.7.6.2/1, entendi que o tipo de elemento não pode ser um tipo de função nem um tipo incompleto, mas depois entendi que um tipo de elemento pode ser um tipo de objeto e um tipo derivado. Em 6.7.6.2/3, se o tipo for derivado, podemos criar um array de tipo derivado. E, na minha opinião, array é um tipo derivado que pode ser classificado como tipo de objeto. Mas esta é apenas a minha opinião, não digo que isso seja verdade. Se eu estiver errado, por favor, explique o porquê.

arrays
  • 3 respostas
  • 217 Views

Sidebar

Stats

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

    Reformatar números, inserindo separadores em posições fixas

    • 6 respostas
  • Marko Smith

    Por que os conceitos do C++20 causam erros de restrição cíclica, enquanto o SFINAE antigo não?

    • 2 respostas
  • Marko Smith

    Problema com extensão desinstalada automaticamente do VScode (tema Material)

    • 2 respostas
  • Marko Smith

    Vue 3: Erro na criação "Identificador esperado, mas encontrado 'import'" [duplicado]

    • 1 respostas
  • Marko Smith

    Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores?

    • 1 respostas
  • Marko Smith

    Como faço para corrigir um erro MODULE_NOT_FOUND para um módulo que não importei manualmente?

    • 6 respostas
  • Marko Smith

    `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso?

    • 3 respostas
  • Marko Smith

    Um programa vazio que não faz nada em C++ precisa de um heap de 204 KB, mas não em C

    • 1 respostas
  • Marko Smith

    PowerBI atualmente quebrado com BigQuery: problema de driver Simba com atualização do Windows

    • 2 respostas
  • Marko Smith

    AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos

    • 1 respostas
  • Martin Hope
    Fantastic Mr Fox Somente o tipo copiável não é aceito na implementação std::vector do MSVC 2025-04-23 06:40:49 +0800 CST
  • Martin Hope
    Howard Hinnant Encontre o próximo dia da semana usando o cronógrafo 2025-04-21 08:30:25 +0800 CST
  • Martin Hope
    Fedor O inicializador de membro do construtor pode incluir a inicialização de outro membro? 2025-04-15 01:01:44 +0800 CST
  • Martin Hope
    Petr Filipský Por que os conceitos do C++20 causam erros de restrição cíclica, enquanto o SFINAE antigo não? 2025-03-23 21:39:40 +0800 CST
  • Martin Hope
    Catskul O C++20 mudou para permitir a conversão de `type(&)[N]` de matriz de limites conhecidos para `type(&)[]` de matriz de limites desconhecidos? 2025-03-04 06:57:53 +0800 CST
  • Martin Hope
    Stefan Pochmann Como/por que {2,3,10} e {x,3,10} com x=2 são ordenados de forma diferente? 2025-01-13 23:24:07 +0800 CST
  • Martin Hope
    Chad Feller O ponto e vírgula agora é opcional em condicionais bash com [[ .. ]] na versão 5.2? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench Por que um traço duplo (--) faz com que esta cláusula MariaDB seja avaliada como verdadeira? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng Por que `dict(id=1, **{'id': 2})` às vezes gera `KeyError: 'id'` em vez de um TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos 2024-03-20 03:12:31 +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