Ir ao conteúdo

Posts recomendados

Postado

Boa tarde! o professor pediu essa questão "programa em que seja possível manipular ponteiros e ponteiros para ponteiros (dereferência) em uma operação que envolva vetores passados como parâmetro para uma função. O que a função deve fazer? eu não consegui entender como fazer isso, só consegui colocar os valores e os endereços os resto eu consigo fazer com um único número inteiro mais com vetor não consigo. li o livro "guia para programação em linguagem C " mais não ajudou nessa parte. coloquei 4 no for para ficar mais fácil de manipular. 

#include <stdio.h>

int main()
{
	int a,i;
	int vet[10]{};
	int *ptrVet;
	int *PtrA, **pptrA;//dereferencia
	
	ptrVet=vet;
	PtrA=vet;
	pptrA=&PtrA;
	
	for(i=0;i<4;i++){
	printf("Digite os valores para preencher o vetor:");
	scanf("%d", &vet[i]);
	}
	
	
	puts("\n========vetor carregado========\n");
	printf("Conteudo do ptrVet: %d\n", *ptrVet);
	printf("Conteudo do PtrA: %d\n", *PtrA);
	printf("Conteudo do pptrA: %d\n", **pptrA);
	printf("\nEndereco do vetor:\n 0-%p\n 1-%p\n 2-%p\n 3-%p\n 4-%p\n 5-%p\n 6-%p\n 7-%p\n 8-%p\n 9-%p\n", vet[0], vet[1], vet[2], vet[3],vet[4],vet[5],vet[6],vet[7],vet[8],vet[9]);
	printf("\nconteudo do vetor:\n\n 0-%d\n 1-%d\n 2-%d\n 3-%d\n 4-%d\n 5-%d\n 6-%d\n 7-%d\n 8-%d\n 9-%d ", vet[0], vet[1], vet[2], vet[3],vet[4],vet[5],vet[6],vet[7],vet[8],vet[9]);
}//fim do programa

 

Postado

Provavelmente seu professor poderia ter explicado melhor...

 

Todo programa em C tem um exemplo potencial disso e deveria ser o segundo programa a ser ensinado num curso de C... Minha opinião apenas. E não ensino ninguém ;) diretamente

 

Você declarou main() assim
 

    int main()

 

e está incompleto: poderia ter escrito 

 

int main(void) 


deixando claro que não vai usar os argumentos, mas entenda que a assinatura de main() é desde sempre

 

    int main( int argc, char** argv)

 

E assim TODO programa em C tem um exemplo simples e prático disso que você precisa fazer: um bloco de ponteiros para ponteiros, que são os argumentos da linha de comando.  Postei aqui um exemplo ontem eu acho. Pode ver aqui pesquisando pelo conteúdo que eu postei. Não me lembro agora. Imagine que seu programa seja exp.c e você vá compilar usando o gcc no Windows ou Linux
 

    gcc -o exp.exe -Wall -std=c17 exp.c


Só uma linha de comando. Se um programa em C chamado gcc receber uma linha dessas vai ter em main()  argc = 6 e vai ter um vetor de ponteiros para string, o tal argv, com 6 strings:
 

argv[0] = "gcc"
argv[1] = "-o"
argv[2] = "exp.exe"
argv[3] = "-Wall"
argv[4] = "--std=c17"
argv[5] = "exp.c"

 

Essa é uma aplicação do que seu professor te pediu para fazer.

 

De volta a seu programa


Não declare assim:
 

	int *PtrA, **pptrA;


É um vício ruim. Se está aprendendo agora evite contrair tal vício. É óbvio que está certo, para o compilador. No entanto está declarando o que? PtrA e pptrA. Só isso. Duas variáveis. O que é PtrA? Um ponteiro para int. O que é pptrA? um ponteiro para um ponteiro para int. 

 

Não declare mais de uma variável por linha.

 

Inicialize todas as variáveis.

 

Seja coerente com os nomes. Se um é Ptr o outro deveria ser PPtr.

 

Escreva
 

    int*     ptrA =   NULL;
    int**    pptrA =  NULL;

 

porque é isso que está declarando. ptrA é int* e pptrA é int**. E não ficará contando asteriscos no meio de declarações quando seus programas forem maiores...

 

E entenda que se pptrA é int** então

  • *pptrA é int*
  • **pprtA é um int
  • o asterisco sai de um lado e aparece do outro.

Se em main argv é char**, então

  • argv[0] é o primeiro parâmetro, e é char*, e pode ser escrito *argv
  • *argv[0] é um char, a primeira letra do primeiro argumento.
Citação

Entender isso em C ou C++ é absolutamente essencial

 

Um exemplo de ponteiro de ponteiro, numa planilha.

 

Não, não está fora do tópico...

image.png.611808f160338cf2b1bbd78154fd3c59.png

 

 

 

Bloco1 e Bloco2 em seu programa poderiam ser esse int[10], um vetor de int.

 

Nas células E2 e E3 tem referências a esse bloco de int.

 

E nas células em amarelo tem a soma dos valores apontados pelo bloco CUJO NOME está em E2 e E3. É isso que seu programa deve fazer. Sua função vai receber um endereço de um ponteiro que aponta para um bloco desses. Se mudar o nome do bloco muda o resultado da função.

 

Nas planilhas do Google --- programáveis em javascript --- tem comandos para fazer essas referências. Em C tem os asteriscos :D 

 

Um pouco off-topic

 

E isso não para em int**, ou char** como em main(). Com um pouco de paciência se pode concluir que um texto pode ser visto como uma coleção de linhas, e lido como um folclórico char** **. E eu falo sério. Um bloco de planilhas como o WorkBook do Excel é um char** ** **!! Um arquivo csv é char** **, por exemplo.

 

Veja o exemplo que postei ontem. Escreva mais se não entendeu.

 

 

 

Postado
26 minutos atrás, arfneto disse:

Só uma linha de comando. Se um programa em C chamado gcc receber uma linha dessas vai ter em main()  argc = 6 e vai ter um vetor de ponteiros para string, o tal argv, com 6 strings:
 


argv[0] = "gcc"
argv[1] = "-o"
argv[2] = "exp.exe"
argv[3] = "-Wall"
argv[4] = "--std=c17"
argv[5] = "exp.c"

@arfneto essa parte eu estou boiando. Para falar a verdade eu entendi na teoria a questão do endereçamento por ponteiros que representa o endereço na memória e não o valor armazenado. mas nesse caso eu estou boiando porque não entendi o que é para fazer. Esse programa foi feito com base no algoritmo dado em aula. então fiz da mesma forma, mais não faço ideia de como isso:

ptrVet=vet;

PtrA=vet;
pptrA=&PtrA;

vai fazer o armazenamento para para imprimir no printf.

Postado

você entendeu a planilha como mostrei?

 

1 hora atrás, darcio ramires disse:

essa parte eu estou boiando

 

é exatamente o propósito de seu programa. Se não entendeu isso nem a planilha não faça o programa ainda, porque vai ter muito mais trabalho

 

Você sabe o que é uma linha de comando? Já compilou um programa assim ao menos?

 

Quando você roda um programa o que tiver na linha de comando é enviado para o programa, como parâmetros de main(). Não entendo porque não ensinam isso.

 

Rodar os programas apenas dentro do IDE até dar certo. Entregar. Esquecer. Essa parece ser a realidade de aprender essas coisas.

 

Só que não é. Quando um programa fica pronto ele COMEÇA a existir:  o autor é pago. O programa começa a ser usado. Em outras máquinas. Outros países, coisas assim.

 

main() 

 

E assim todo programa em C ou C++ ou todo script ou batch ou programa em qualquer linguagem precisa desses parâmetros. Se seu programa no Windows é P.EXE e você vai no terminal e digita

    P um.TXT /C teste

essas coisas são argumentos e são passadas para o programa. Isso vem na forma de um vetor de strings como eu te expliquei. Nesse caso 4 delas, claro. Numeradas de 0 a 3 no vetor argv. argv[3] nesse caso vai ser "teste"

 

E é isso que seu programa vai fazer.

 

Essa noção é essencial em C e  nos sistemas em geral. Por exemplo a noção do endereço de um vetor de ponteiros é o que move o Windows e o Linux e um site por exemplo: Os controles --- botões, imagens --- numa página web são tratados por exemplo por um vetor de ponteiros para funções que tratam cada click em cada componente

  • Obrigado 1
Postado

@darcio ramires

Em 01/12/2020 às 20:27, darcio ramires disse:

mas nesse caso eu estou boiando porque não entendi o que é para fazer

 

Em 01/12/2020 às 17:07, darcio ramires disse:

programa em que seja possível manipular ponteiros e ponteiros para ponteiros (dereferência) em uma operação que envolva vetores passados como parâmetro para uma função. O que a função deve fazer?

 

Não respondeu a nada do que perguntei.

 

Entenda que a função é você que vai escrever e pode fazer qualquer coisa. Por exemplo imitar a planilha que eu te mostrei
 

image.png.3d2b4a218002b3041375bf6a8b8be03e.png

 

e escrever uma função que soma os elementos de um vetor de int, ao receber o endereço de um ponteiro para eles...

 

O enunciado é liberal. Basta que faça o que está escrito.

 

Isso é muito comum em C porque a linguagem foi escrita para isso. C foi escrita para ser uma alternativa a escrever sistemas operacionais em Assembler num PDP-11, um computador dos velhos tempos. O sistema era o Unix. E tinha um game envolvido também ;) . E em sistemas é muito comum passar e receber endereços de áreas de memória em funções.

 

Entenda que ao declarar
 

    int**   coisa = NULL;

 

a única garantia que se tem é que *coisa aponta para um int, e **coisa é o valor desse int. No fundo nem isso é garantido, já que se pode gravar qualquer coisa em uma variável em C.

 

Quando você declara isso precisa planejar e construir o que vai estar lá, ou confiar que seja o que espera se vai receber de algum lugar. No caso que expliquei de main() o sistema constrói **argv como um vetor de ponteiros, um depois do outro, e coloca o endereço do primeiro deles em *argv. E o total deles em argc.

 

Isso é uma coisa que vai acompanhar sempre esses vetores: em algum lugar precisa saber quantos elementos tem lá. Como eu disse antes, um arquivo csv por exemplo pode ser visto como char** **, mas você precisa de dois int: um com o total de campos por registro e outro com o total de registros.

 

De volta ao programa:

 

Vou mostrar um exemplo com essas coisas. Em 3 casos

 

caso 1: int** coisa aponta para um vetor de int.

 

Em C sempre tem essa dualidade entre vetor e ponteiro e char* e char[ ]. É preciso se acostumar. Nesse primeiro caso coisa vai ser como na planilha que mostrei. E está aqui acima... Vamos cortar os vetores pela metade: 5 elementos já está bem ;) 
 

    int     vetor1[] = { 1,2,3,4,5 };
    int     vetor2[] = { -10,-20, -30, -40, -50 };

 

Então eu posso ter um ponteiro para esses blocos, como na planilha:
 

    int**   bloco1 = (int**) &vetor1[0];
    int**   bloco2 = (int**) vetor2;

 

O cast (int**) é opcional. Essas notações são equivalentes. Isso aqui é um exemplo de poucas linhas, abusando de recortar e colar ;)  Eu uso sempre o cast para eu ver que foi de propósito que eu escrevi. Muita gente usa assim, evitanto conversões implícitas a qualquer custo. O que importa é que bloco1 e bloco2 apontam para os vetores, como na planilha.

 

Uma função óbvia para o caso 1:
 

    int     mostra_vetor(int,int**);


Outra função óbvia para o caso 1:

 

    int     soma_vetor(int,int**);

 

Claro, faz sentido uma função que soma QUALQUER vetor e uma função que mostra QUALQUER vetor de int.

 

O que não é óbvio:

 

Nessas funções se poderia passar apenas o endereço do vetor, já que os elementos vem um depois do outro na memória. Ao passar o vetor se pode alterar o conteúdo dele, o bloco1 ou o bloco2. Mas não o valor do ponteiro em si. Isso é essencial no caso de listas ligadas por exemplo, em que o endereço de início da lista pode mudar e acho mais da metade dos iniciantes passa o endereço da lista na hora de inserir e fica intrigado de nunca dar certo quando retorna da função que insere() :D

 

Nesse caso por exemplo imagine uma função que recebe um ponteiro desses, mas compara o vetor recebido com todos que ela já viu e torna o endereço daquele em que a soma dos elementos é a maior até o momento: um max_vetor_int(). Serve pra você entender o problema: você pode receber um NOVO endereço de vetor.

 

caso 2: int** coisa aponta para um vetor. Mas de int*

 

Esse é similar ao caso de main() e muito comum: no lugar apontado por coisa tem uma série de ponteiros para int, ao invés de uma série de int um depois do outro. 

 

Imagine um vetor de blocos, e vamos colocar neles o endereço de bloco1 e de bloco2.

 

Um exemplo mais C-fashion seria uma função que recebe uma lista de ponteiros para vetores de int e retorna um vetor com os ponteiros apontando para eles por ordem de soma. Acho que dá pra entender. C foi escrita para isso. Não para ler listas do teclado.

 

Como construir um bloco de ponteiros para vetores para int

 

Desse jeito, como se escreve em português:
 

    // caso 2
    int     n_blocos = 2; // para esse exemplo
    int**   p_bloco = (int**)malloc(n_blocos * sizeof(int*));
    // cria os dois ponteiros e coloca o endereco 
    // em p_bloco, claro.
    // marca os enderecos dos dois blocos no vetor
    // que afinal foi criado para isso
    p_bloco[0] = (int*) &vetor1;
    p_bloco[1] = (int*) &vetor2;
  • declara o int**
  • faz com que ele aponte para uma área suficiente para conter 2 ponteiros para int
  • copia os endereços dos ponteiros para o lugar certo

Se isso está certo então
 

    printf("primeiro valor do bloco 1: %d\n", *p_bloco[0]);
    printf("primeiro valor do bloco 2: %d\n", *p_bloco[1]);

 

através de p_bloco eu posso acessar o primeiro int de cada bloco para conferir com vetor1 e vetor2...

 

caso 3: acessando um int a partir de um ponteiro de um ponteiro para ele

 

Esse é um caso mais raro. Em geral o que se quer é acessar ponteiros para estruturas e funções através de um vetor de ponteiros. Mas o trivial é isso:
 

    int     Valor =   -4567;
    int*    pValor =  &Valor;
    int**   ppValor = &pValor;

 

E as 3 variáveis apontam para a mesma coisa. Por isso é interessante e mais legível declarar o que é o que e não deixar asteriscos soltos pelo código... pValor é int*, ppValor é int**. 
 

    int     Valor = -4567, * pValor = &Valor, * * ppValor = &pValor;

 

Para o compilador isso acima é exatamente a mesma coisa que as outras linhas. Mas para quem lê o programa é um inferno. Se acha melhor usar desse modo mais compacto, recomendo não beber mais. :) e buscar 💊

 

De todo modo esse trecho
 

    printf("\nAcessando um int:\n");
    int     Valor = -4567;
    int*    pValor = &Valor;
    int**   ppValor = &pValor;

    printf("\natraves da variavel:\t\t\t%d\n",
        Valor);
    printf("\nusando um ponteiro para a variavel:\t%d\n",
        *pValor);
    printf("\nusando um ponteiro para esse ponteiro:\t%d\n",
        **ppValor );

 

vai mostrar

 

Acessando um int:

atraves da variavel:                    -4567

usando um ponteiro para a variavel:     -4567

usando um ponteiro para esse ponteiro:  -4567

 

O programa todo mostra

 


Bloco1
vetor tem 5 int: [     1      2      3      4      5   ]
vetor tem 5 int: [      Soma: 15
Somando 2 a cada elemento
vetor tem 5 int: [     3      4      5      6      7   ]

Bloco2
vetor tem 5 int: [   -10    -20    -30    -40    -50   ]
vetor tem 5 int: [      Soma: -150
Somando 10 a cada elemento
vetor tem 5 int: [     0    -10    -20    -30    -40   ]

Criando vetor de ponteiros

primeiro valor do bloco 1: 3
primeiro valor do bloco 2: 0

Acessando um int:

atraves da variavel:                    -4567

usando um ponteiro para a variavel:     -4567

usando um ponteiro para esse ponteiro:  -4567

 

Eis o programa de teste
 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int     incrementa_vetor(int, int**, int);
int     mostra_vetor(int,int**);
int     soma_vetor(int,int**);

int main(int argc, char** argv)
{
    int     vetor1[] = { 1,2,3,4,5 };
    int     vetor2[] = { -10,-20, -30, -40, -50 };
    int**   bloco1 = (int**) &vetor1[0];
    int**   bloco2 = (int**) vetor2;


    printf("\nBloco1\n");
    mostra_vetor(5, bloco1);
    printf("\tSoma: %d\n",
        soma_vetor(5, bloco1));
    incrementa_vetor(5, bloco1, 2);
    mostra_vetor(5, bloco1);

    printf("\nBloco2\n");
    mostra_vetor(5, bloco2);
    printf("\tSoma: %d\n", 
    soma_vetor(5, bloco2));
    incrementa_vetor(5, bloco2, 10);
    mostra_vetor(5, bloco2);

    // p_blocos eh um vetor de ponteiros, para int
    // para blocos de int
    // p_blocos[0] aponta para o primeiro
    // p_blocos[1] aponta para o N-esimo bloco

    // cria o bloco
    printf("\nCriando vetor de ponteiros\n\n");

    // caso 2
    int     n_blocos = 2; // para esse exemplo
    int**   p_bloco = (int**)malloc(n_blocos * sizeof(int*));
    // cria os dois ponteiros e coloca o endereco 
    // em p_bloco, claro.
    // marca os enderecos dos dois blocos no vetor
    // que afinal foi criado para isso
    p_bloco[0] = (int*) &vetor1;
    p_bloco[1] = (int*) &vetor2;

    printf("primeiro valor do bloco 1: %d\n", *p_bloco[0]);
    printf("primeiro valor do bloco 2: %d\n", *p_bloco[1]);

    printf("\nAcessando um int:\n");
    int     Valor = -4567;
    int*    pValor = &Valor;
    int**   ppValor = &pValor;

    printf("\natraves da variavel:\t\t\t%d\n",
        Valor);
    printf("\nusando um ponteiro para a variavel:\t%d\n",
        *pValor);
    printf("\nusando um ponteiro para esse ponteiro:\t%d\n",
        **ppValor );

    free(p_bloco);

    return 0;
};

int incrementa_vetor(int argc, int** argv, int inc)
{
    int soma = 0;
    int* vetor = (int*)argv;
    printf("Somando %d a cada elemento\n", inc);
    for (int i = 0; i < argc; i += 1)
        vetor[i] += inc;
    return 0;
}

int mostra_vetor(int argc, int** argv)
{
    int* vetor = (int*) argv;
    printf("vetor tem %d int: [ ", argc);
    for (int i = 0; i < argc; i += 1)
        printf("%5d  ", vetor[i]);
    printf(" ]\n");
    return 0;
}

int soma_vetor(int argc, int** argv)
{
    int soma = 0;
    int* vetor = (int*)argv;
    printf("vetor tem %d int: [ ", argc);
    for (int i = 0; i < argc; i += 1)
        soma += vetor[i];
    return soma;
}

 

  • Obrigado 1
Postado
Em 01/12/2020 às 22:02, arfneto disse:

Você sabe o que é uma linha de comando? Já compilou um programa assim ao menos?

@arfneto Bom dia! obrigado pela explicação está me ajudando muito! quanto a primeira pergunta acreditava que sim, mais não sei, estou lendo alguns artigos para compreender melhor. Já a segunda só fiz uma vezes junto com o professor e bem similar ao código que postei primeiro.

No código que enviou eu entendi  o carregamento do vetor e a formação dos blocos 1 e 2, que int**  está apontado para o valor do vetor e int* marca o endereço do vetor e as funções criadas.

Quanto ao comando argv estou lendo artigos para entender melhor (nunca tinha visto).

O caso 3 eu entendi que valor=x , int* = valor=x, int** = int* = valor=x). 

Vou estudar mais e procurar alguns exemplos para fazer. 

muito obrigado.

 

Postado
3 horas atrás, darcio ramires disse:

O caso 3 eu entendi que valor=x , int* = valor=x, int** = int* = valor=x). 

Vou estudar mais e procurar alguns exemplos para fazer

 

O caso mais importante é o 2. E eu citei exemplos deles todos. Porque simplesmente não programa os exemplos de que falei?

 

3 horas atrás, darcio ramires disse:

Quanto ao comando argv estou lendo artigos para entender melhor (nunca tinha visto).

 

É curioso que não falem sobre isso em aula. Todo programa que roda no sistema tem isso, usa isso e recebe isso. TODO.

 

Eu postei um exemplo ou dois. Porque não programa esses?

image.thumb.png.a9ab71e3bb0c277c75b32ab850e427d2.pngEsse exemplo, claro...

  • Curtir 1
Postado

 Um pouco de contexto:

 

Um programa que não trate a linha de comando é uma bobagem. Apenas programas absolutamente simples de testes para principiantes não ganhariam nada com argumentos.

 

Imagine

  • se o compilador abrisse uma tela e perguntasse: "qual programa deseja compilar agora"? E seu sistema tivesse 180 programas.
  • se o navegador abrisse um único site sempre
  • um dir na console perguntasse qual o diretório que deseja listar
  • um jogo de tiro mostrasse uma linha perguntando: quantos tiros deseja dar? Digite a direção e o número de tiros e tecle ENTER!
  • um programa que trata arquivos de produto ficasse parado pedindo o nome da tela em um terminal
  • um programa que cria uma lista ligada ficasse de fato esperando você digitar todos os nós iniciais na tela. E o nome do arquivo para salvar os dados ao final

E tem o pior: imagine ter que compilar o programa de novo só porque mudou o nome do arquivo em 
 

    const char* padrão = "entrada.txt";

 

Qualquer um que vá usar o seu programa vai ter que ter o programa em C? Sério? Em outra máquina? E um compilador? Um IDE completo talvez? Não vai funcionar.

 

Veja a diferença
 

    const char* padrão = "entrada.txt";
    char        arquivo[80];

    if (argc > 1)
        strcpy(arquivo, argv[1]);
    else
        strcpy(arquivo, padrão);

    printf("Vai abrir \"%s\"\n", arquivo);
    FILE* E = fopen(arquivo, "r");
    if (E == 0) return -1; // nao abriu

 

Isso é o que você quer: digita o nome do arquivo JUNTO com o programa. Se não digitou nada, aí sim usa o nome padrão.

 

Um último exemplo: gcc -v

 

Sim, gcc é um compilador C. Mas o sistema não sabe

 

Imagine, numa máquina que tenha esse gcc instalado,  um programa em Windows chamado gcc.c gerando um executável chamado gcc.exe... e uma pasta forum

 

Esse comando tem parâmetros:
 

    dir /o:d

 

lista os arquivos por ordem de data. argc seria 2, argv[0] seria "dir" e argv[1] seria "/o:d"

 


C:\Users\toninho\AppData\Local\Temp\forum>dir /o:d
 O volume na unidade C não tem nome.
 O Número de Série do Volume é 7E52-1BF2

 Pasta de C:\Users\toninho\AppData\Local\Temp\forum

03/12/2020  15:06               202 gcc.c
03/12/2020  15:24                 7 1.txt
03/12/2020  15:49    <DIR>          ..
03/12/2020  15:49    <DIR>          .
               2 arquivo(s)            209 bytes
               2 pasta(s)   106.499.739.648 bytes disponíveis

 

Nessa pasta forum tem 2 arquivos então. Se rodar gcc -v nessa pasta:

 

C:\Users\toninho\AppData\Local\Temp>gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=c:/bin/mingw/bin/../libexec/gcc/mingw32/9.2.0/lto-wrapper.exe
Target: mingw32
Configured with: ../src/gcc-9.2.0/configure --build=x86_64-pc-linux-gnu\
--host=mingw32 --target=mingw32 --disable-win32-registry --with-arch=i586\
--with-tune=generic --enable-static --enable-shared --enable-threads\
--enable-languages=c,c++,objc,obj-c++,fortran,ada --with-dwarf2 --disable-sjlj-exceptions\
--enable-version-specific-runtime-libs --enable-libgomp --disable-libvtv\
--with-libiconv-prefix=/mingw --with-libintl-prefix=/mingw --enable-libstdcxx-debug\
--disable-build-format-warnings --prefix=/mingw --with-gmp=/mingw --with-mpfr=/mingw\
--with-mpc=/mingw --with-isl=/mingw --enable-nls --with-pkgversion='MinGW.org GCC Build-2'
Thread model: win32
gcc version 9.2.0 (MinGW.org GCC Build-2)

C:\Users\toninho\AppData\Local\Temp>

 

 

"-v" é o argumento para mostrar a versão e as opções padrão do compilador...

 

E o gcc.c?


Tem 3 linhas: o printf() o for() e o return

 

#include <stdio.h>

int main(int argc, char** argv)
{
    printf("\nargc: %d\n\n", argc);
    for( int i = 0; i< argc; i+=1) printf("argv[%d]\t='%s'\n\n", i, argv[i]);
    return 0;
};

 

Gerando gcc.exe co o comando que eu te mostrei

 

gcc -o gcc.exe -Wall -std=c17 gcc.c

 

e listando o diretório

 


C:\Users\toninho\AppData\Local\Temp\forum>gcc -o gcc.exe -Wall -std=c17 gcc.c

C:\Users\toninho\AppData\Local\Temp\forum>dir /o:d
 O volume na unidade C não tem nome.
 O Número de Série do Volume é 7E52-1BF2

 Pasta de C:\Users\toninho\AppData\Local\Temp\forum

03/12/2020  15:06               202 gcc.c
03/12/2020  15:24                 7 1.txt
03/12/2020  15:51    <DIR>          ..
03/12/2020  15:51    <DIR>          .
03/12/2020  15:51           120.682 gcc.exe
               3 arquivo(s)        120.891 bytes
               2 pasta(s)   106.498.420.736 bytes disponíveis

 

Pois é: agora apareceu o resultado da compilação: gcc.exe.

 

Rodando gcc -v de novo:
 

C:\Users\toninho\AppData\Local\Temp\forum>gcc -v

argc: 2

argv[0] ='gcc'

argv[1] ='-v'


C:\Users\toninho\AppData\Local\Temp\forum>

 

Como já tem um gcc no diretório corrente o CMD no Windows ingenuamente usa esse antes do compilador, já que os dois tem o mesmo nome. O Terminal do Windows não faria isso. Nem o Linux.

 

E "-v" é o único argumento. E "gcc" é o nome do programa, que sempre vem em argv[0]. Veja o fonte em C

 

Rodando o exemplo que te mostrei e que usei para geral o programa aqui

 


C:\Users\toninho\AppData\Local\Temp\forum>gcc -o gcc.exe -Wall -std=c17 gcc.c

argc: 6

argv[0] ='gcc'

argv[1] ='-o'

argv[2] ='gcc.exe'

argv[3] ='-Wall'

argv[4] ='-std=c17'

argv[5] ='gcc.c'

 

Agora o sistema roda o programa gcc.exe que foi compilado e não o compilador, e o programa exemplo mostra os parâmetros como eu te disse que faria

E espero que agora tenha dado para entender como funciona isso e porque é tão importante...

 

 

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

LANÇAMENTO!

eletronica2025-popup.jpg


CLIQUE AQUI E BAIXE AGORA MESMO!