-
Posts
6.526 -
Cadastrado em
-
Última visita
Tipo de conteúdo
Artigos
Selos
Livros
Cursos
Análises
Fórum
Tudo que arfneto postou
-
Como conectar ao modem Vivo após mudar ele pra Bridge
arfneto respondeu ao tópico de doraimom em Redes e Internet
Pois é: ao colocar o modem em modo bridge ele deixa de ser um roteador, então não teria sentido ter IP ou servidor DHCP. Ele serve apenas como uma caixa preta que trás o acesso a internet até sua rede local. O que acontece lá dentro do modem é problema da operadora, desde que você tenha acesso à internet no dispositivo que você ligar nele. E aí você liga nele o que você quiser ou precisar, e tem a segurança de que está tudo como você quer. Por isso em empresas se procura algo assim: apenas um cabo de rede, de fibra, de isopor, qualquer coisa que você conecta nos seus roteadores e tudo funciona, de modo que você pode trocar de operadora ou de modem e não ter que se preocupar com nada. E você pode controlar segurança e acesso e DHCP e tudo que precisa. Você coloca o modem em bridge justamente para colocar seus roteadores e servidores como você quer. O modem só trás o sinal. O que está estranho no seu caso é que o processo de colocar o modem em modo bridge deveria ter desligado automaticamente o wifi, como desligaria seus telefones e TV e todos os servicós de rede rodando no seu modem/roteador. Em geral você coloca o modem em modo bridge justamente para não ter que acessá-lo. Em geral quando se faz isso é porque não se quer ter qualquer possível influência entre o que acontece no modem e o que acontece na sua rede, exceto o óbvio: acesso a internet. A configuração do aparelho enquanto modem em geral etá muito fora do conhecimento do usuário comum e inclui parâmetros específicos para o modem operar na rede da operadora e não na sua rede local. Os roteadores oferecidos pelas operadoras evoluiram para um conceito de set-top box hoje em dia, com um grande número de funções e um mínimo de configuração, visando diminuir os custos de suporte e a chance de problemas, então isso rapidamente escala para uma situação de risco para redes de empresas ou mesmo domésticas um pouco mais sofisticadas, e por isso a possibilidade de usar o modo bridge se torna às vezes obrigatória. E às vezes impossível. vou te dar um exemplo curto, citando um aparelho ao qual tive acesso hoje. trata-se de uma conexão via fibra ótica da operadora VIVO via um modem roteador que tem uma porta WAN e tres portas LAN todas gigabit, duas portas RJ11 para telefone, e saída coaxial e rádio dual-band 2.4 e 5 Ghz, na minha cidade, São Paulo. Muito comum aqui. O aparelho usa o endereço IP 192.168.15.1 e até onde eu sei não da pra alterar. Ele permite o redirecionamento de portas, mas tem um limite: a tabela tem apenas oito entradas, se não estou enganado. Até onde eu sei, não tem sequer uma opção para backup de sua configuração em disco. Bom candidato a ser colocado em modo bridge só por essas razões. Estou certo de que tem outras se continuar usando. Por outro lado, ao ser colocado em bridge lá se vão TODOS os outros recursos. Não tem opção de desligar tudo que envolve roteamento e TCP/IP e simplesmente conectar o infeliz a uma porta no patch-panel e daí pra minha rede, MAS continuar usando as duas linhas telefônicas que estão ligadas no PABX, a TV na recepção e na sala de reuniões... Tudo ou nada. Se passar pra brigge precisa fazer outro contrato para os outros serviços. Em resumo, voltando ao tópico: você coloca o modem em modo bridge em geral para esquecer dele, simplesmente por razões de performance, de configuração, de segurança ou em geral por todas essas: você pode precisar de vários servidores DHCP com tempos de lease variáveis, redes wifi distintas, um grande número de redirecionamentos, uma tabela de rotas sofisticada, suporte 24x7 em minutos e não "até o proximo dia útil" e coisas assim. Pode precisar de mais de um provedor de acesso a internet para manter seu negócio rodando, e vai descobrir que esses aparelhos de operadoras não foram feitos para conviver na mesma rede... -
Como conectar ao modem Vivo após mudar ele pra Bridge
arfneto respondeu ao tópico de doraimom em Redes e Internet
Ao colocar o modem/roteador em modo bridge ele deveria desativar todas as funções exceto as do modem, que passa a funcionar como se pode imaginar, ponte ou "bridge" entre sua rede e a internet. Isso implica em desativar telefonia, TV e funções de roteamento e deveria incluir desativar as antenas e a rede wifi. Estranho continuar ativa a rede sem fio. Não é estanho que não funcione, claro. É importante voltar a acessar o modem só para desativar um recurso que não funciona na prática? Se precisa mesmo disso apenas retorne o modem às configurações de fábrica e desative o wifi antes de colocar em modo bridge de novo. Para fazer isso você liga o modem e mantem apertado o botão de reset e tal.... -
N sei como desbloquear a velocidade placa de rede.
arfneto respondeu ao tópico de xGrimReaper17x em Redes e Internet
Poida ter dito qual a marca e modelo dessa placa... Em geral a configuração da placa é negociada automaticamente ao ligar e não há nada pra se configurar depois. Half/Full Duplex, velocidade, endereços e parâmetros de configuração são negociados para o melhor possível considerando os cabos usados e o que está conectado de cada lado. A única coisa que me recordo de configurar em anos usando isso é ativar ou desativar o reconhecimento de certos pacotes para poder ligar o micro pela rede --- WOL --- que não é ativado por padrão quando disponível. Claro, tem situações em que precisa desativar um protocolo ou ativar um endereço de rede em particular. Onde conseguiu esse suposto limite de 1,2Mbps? De todo modo estaria acima da capacidade nominal de sua placa de rede, que é de 1Mbps. Note que conexões Gigabit implicam em cabo de 8 vias conectado corretamente, e dispositivo compatível do outro lado: computador, modem, roteador ou switch compatível e habilitado para esse tipo de conexão... -
Não conseguindo acessar PLEX fora da rede
arfneto respondeu ao tópico de Profutxx em Redes e Internet
Olá! Hoje acho que não é mais preciso, apenas associar os seus servidores plex à sua conta plex deve ser suficiente para que eles apareçam no menu de qualquer Plex Player associado a essa mesma conta, seja um telefone, um tablet, uma TV, qualquer coisa. Mas se for preciso programar algo no roteador seria apenas direcionar o tráfego da porta 32400 para o servidor plex, o que limitaria o uso pela internet a um servidor por endereço público. Claro, se mudou a porta do servidor tem que mudar o tráfego de acordo -
Olá! "Executar o arquivo dentro da source" e "puxá-lo de outro local do computador" são expressões que não entendi de fato. Como não postou o conteúdo de Xited.reg não dá pra ter certeza do que quer fazer, mas imagino que seja como de costume um arquivo texto com algo a ser gravado ou lido no registro do sistema. Usar system() para executar o arquivo vai invocar o editor de registro se o editor de registro do windows estiver de fato configurado para abrir arquivos com extensão reg e é isso que você não quer fazer, já que disse que quer alterar chaves e valores de registro em seu programa Entenda que uma coisa é alterar chaves e valores do registro em C++ e outra é processar arquivos reg em seu programa C++ alterar valores e chaves de registro em C++ Isso está bem documentado na fonte suprema dessas informações, a documentação do windows em http://docs.microsoft.com Lá você pode ver um programa de exemplo, que funciona direitinho, para listar chaves de registro, nesta página Eis o programa, só pra você poder dar uma olhada sem ter que ir até outro site: // QueryKey - Enumerates the subkeys of key and its associated values. // hKey - Key whose subkeys and values are to be enumerated. #include <windows.h> #include <stdio.h> #include <tchar.h> #define MAX_KEY_LENGTH 255 #define MAX_VALUE_NAME 16383 void QueryKey(HKEY hKey) { TCHAR achKey[MAX_KEY_LENGTH]; // buffer for subkey name DWORD cbName; // size of name string TCHAR achClass[MAX_PATH] = TEXT(""); // buffer for class name DWORD cchClassName = MAX_PATH; // size of class string DWORD cSubKeys=0; // number of subkeys DWORD cbMaxSubKey; // longest subkey size DWORD cchMaxClass; // longest class string DWORD cValues; // number of values for key DWORD cchMaxValue; // longest value name DWORD cbMaxValueData; // longest value data DWORD cbSecurityDescriptor; // size of security descriptor FILETIME ftLastWriteTime; // last write time DWORD i, retCode; TCHAR achValue[MAX_VALUE_NAME]; DWORD cchValue = MAX_VALUE_NAME; // Get the class name and the value count. retCode = RegQueryInfoKey( hKey, // key handle achClass, // buffer for class name &cchClassName, // size of class string NULL, // reserved &cSubKeys, // number of subkeys &cbMaxSubKey, // longest subkey size &cchMaxClass, // longest class string &cValues, // number of values for this key &cchMaxValue, // longest value name &cbMaxValueData, // longest value data &cbSecurityDescriptor, // security descriptor &ftLastWriteTime); // last write time // Enumerate the subkeys, until RegEnumKeyEx fails. if (cSubKeys) { printf( "\nNumber of subkeys: %d\n", cSubKeys); for (i=0; i<cSubKeys; i++) { cbName = MAX_KEY_LENGTH; retCode = RegEnumKeyEx(hKey, i, achKey, &cbName, NULL, NULL, NULL, &ftLastWriteTime); if (retCode == ERROR_SUCCESS) { _tprintf(TEXT("(%d) %s\n"), i+1, achKey); } } } // Enumerate the key values. if (cValues) { printf( "\nNumber of values: %d\n", cValues); for (i=0, retCode=ERROR_SUCCESS; i<cValues; i++) { cchValue = MAX_VALUE_NAME; achValue[0] = '\0'; retCode = RegEnumValue(hKey, i, achValue, &cchValue, NULL, NULL, NULL, NULL); if (retCode == ERROR_SUCCESS ) { _tprintf(TEXT("(%d) %s\n"), i+1, achValue); } } } } void __cdecl _tmain(void) { HKEY hTestKey; if( RegOpenKeyEx( HKEY_CURRENT_USER, TEXT("SOFTWARE\\Microsoft"), 0, KEY_READ, &hTestKey) == ERROR_SUCCESS ) { QueryKey(hTestKey); } RegCloseKey(hTestKey); } Lá no site tem um botão marcado Copy que copia o código para a área de transferência e você pode colar de lá para seu compilador. Todos os exemplos de código lá tem isso e é mais seguro que tentar copiar daqui, o que geralmente insere caracteres estranhos em seu programa. Toda a lista de funções para manipular o registro em seu programa está lá, em https://docs.microsoft.com/en-us/windows/win32/sysinfo/registry-functions Processar arquivos reg em um programa C++ Isso é uma outra história: claro que no fundo vai acabar usando as mesmas funções, mas terá que abrir o arquivo reg e interpretar o texto lá, testar até onde possível a coerência do que está lá, comando a comando, e identificar a função certa pra executar, chamar a função e seguir para a próxima até o final do arquivo.
-
C++ Gerar vetor em um main através da classe em arquivo de cabeçalho
arfneto respondeu ao tópico de Thiago1101 em C/C#/C++
Voltando ao essencial e aos objetos Imaginei que você ia voltar com um post depois de um crash de seu projeto, mas talvez tenha evoluído no projeto ou tenha se limitado ao contexto do exemplo aqui, já que resolveu seu problema imediato De qualquer forma vou mostrar aqui um pouco do que acontece depois em geral, quando você tem uma classe enjoada como essa dos vetores, que aloca os vetores na hora. Isso porque é um caso genérico bacana como exemplo e pode ser útil pra muitos, por alertas para os riscos ao escrever esse tipo de código em C ou C++: você precisa se preocupar com a memória alocada. Esse trecho de programa int teste_copy_constructor() { cout << "\n-------------------- teste copy constructor --------------------" << endl; cout << "Criando v1 com 4 valores e delta = 3.14159" << endl; MeuVetor v1(4, (float)3.14159); cout << "Criando v2 com 3 valores e delta = 2.0" << endl; MeuVetor v2(3, 2.0); cout << "copiando v1 em v3" << endl; MeuVetor v3 = v1; cout << "copiando v2 em v4" << endl; MeuVetor v4 = v2; cout << endl << "Mostrando v1" << endl; v1.Mostra(); cout << endl << "Mostrando v2" << endl; v2.Mostra(); cout << endl << "Mostrando v3 = v1" << endl; v3.Mostra(); cout << endl << "Mostrando v2 = v4" << endl; v4.Mostra(); cout << "-------------------- teste copy constructor --------------------\n" << endl; return 0; } É o código do exemplo que deixei aqui antes e você chama assim em main() por exemplo: int main() { teste_copy_constructor(); cout << "\nDe volta a main()\n" << endl; E gera isso na tela -------------------- teste copy constructor -------------------- Criando v1 com 4 valores e delta = 3.14159 +++++ Construtor: construindo vetor com 4 valores e delta = 3.14159 Criando v2 com 3 valores e delta = 2.0 +++++ Construtor: construindo vetor com 3 valores e delta = 2 copiando v1 em v3 +++++ Construtor de copia: vetor com 4 valores e delta = 3.14159 copiando v2 em v4 +++++ Construtor de copia: vetor com 3 valores e delta = 2 Mostrando v1 ---------- Vetor com 4 valores. Delta = 3.14159 Pos: 0 Valor: 0 Pos: 1 Valor: 3.14159 Pos: 2 Valor: 6.28318 Pos: 3 Valor: 9.42477 Mostrando v2 ---------- Vetor com 3 valores. Delta = 2 Pos: 0 Valor: 0 Pos: 1 Valor: 2 Pos: 2 Valor: 4 Mostrando v3 = v1 ---------- Vetor com 4 valores. Delta = 3.14159 Pos: 0 Valor: 0 Pos: 1 Valor: 3.14159 Pos: 2 Valor: 6.28318 Pos: 3 Valor: 9.42477 Mostrando v2 = v4 ---------- Vetor com 3 valores. Delta = 2 Pos: 0 Valor: 0 Pos: 1 Valor: 2 Pos: 2 Valor: 4 -------------------- teste copy constructor -------------------- ----- Destrutor: fim da vida para um vetor com 3 valores e delta = 2 ----- Destrutor: fim da vida para um vetor com 4 valores e delta = 3.14159 ----- Destrutor: fim da vida para um vetor com 3 valores e delta = 2 ----- Destrutor: fim da vida para um vetor com 4 valores e delta = 3.14159 De volta a main() E funciona direitinho: cria os quatro vetores: v4 é copia de v2, v3 é cópia de v1, e as cópias alocam memória para o vetor quando preciso e o construtor também. E quando volta do teste para main os vetores perdem o foco e são destruídos, com a memória liberada. Tudo certo então? Não mesmo. Se você escrever esse int teste_atribuicao() { cout << "\n-------------------- teste atribuicao vetor a = vetor b --------------------" << endl; cout << "criou v1 e v2" << endl; MeuVetor v1(2, (float)3.14159); MeuVetor v2(4, (float)2.0); v1.Mostra(); v2.Mostra(); v2 = v1; v2.Mostra(); cout << "copiou. Tera funcionado?" << endl; cout << "-------------------- teste atribuicao vetor a = vetor b --------------------\n" << endl; return 0; } // end teste_atribuicao E rodar assim: teste_atribuicao(); cout << "\nDe volta a main()\n" << endl; Vai ver que seu programa vai pro espaço. Porque? Veja o que sai na tela: -------------------- teste atribuicao vetor a = vetor b -------------------- criou v1 e v2 +++++ Construtor: construindo vetor com 2 valores e delta = 3.14159 +++++ Construtor: construindo vetor com 4 valores e delta = 2 ---------- Vetor com 2 valores. Delta = 3.14159 Pos: 0 Valor: 0 Pos: 1 Valor: 3.14159 ---------- Vetor com 4 valores. Delta = 2 Pos: 0 Valor: 0 Pos: 1 Valor: 2 Pos: 2 Valor: 4 Pos: 3 Valor: 6 ---------- Vetor com 2 valores. Delta = 3.14159 Pos: 0 Valor: 0 Pos: 1 Valor: 3.14159 copiou. Tera funcionado? -------------------- teste atribuicao vetor a = vetor b -------------------- ----- Destrutor: fim da vida para um vetor com 2 valores e delta = 3.14159 ----- Destrutor: fim da vida para um vetor com 2 valores e delta = 3.14159 Parece tudo bem... Criou os dois objetos, depois copiou o primeiro no segundo, imprimiu os valores, e retornou. Mas então... Seu programa aborta e o que vai aparecer depende claro de seu ambiente de execução... A vida é injusta. Porque isso agora? Qualquer operação com variáveis desse tipo, ditas instâncias dessa classe MeuVetor, tem que ser programada com cuidado. Eis o que acontece: quando você declara MeuVetor v1 = v2; MeuVetor v3 = v4; é muito diferente de escrever depois v3 = v1; Na declaração, como você escreveu o construtor de cópia o compilador percebe a parada e chama o construtor correto. Veja as mensagens na tela. E então aloca memória para o vetor novo e copia os dados um a um por conta. E quando vai destruir o objeto o código do destrutor ~MeuVetor() apaga tudo certinho. Mas quando você escreve v3=v1 o compilador vê uma atribuição e na falta de mais informação simplesmente copia todos os valores. Se você chama v3.Mostra() até pode imprimir tudo direitinho, só que o vetor também é copiado, o endereço do vetor. Veja como é a classe: class MeuVetor { public: int quantos; float delta; float * vetor = NULL; /* na construcao do objeto vai ser alocado o tamanho correto */ ... Então quando v1 é destruído v3 aponta para uma região de memória que já foi liberada. E quando você tentar acessar os dados em v3.vetor seu programa já era. E se ele não cancelar pode ser pior porque a área onde estava v3.vetor pode já ter outros dados e vai ser o diabo encontrar um erro desses. Você precisa definir o processo de atribuição para quando aparecer uma linha tipo // para v1, v2 e v3 da classe MeuVetor v3 = v1; /* normal */ v3 = v2 = v1; /* perfeitamente legal */ o código trate de criar os vetores certinho, como no construtor de cópia. É preciso redefinir o operador de atribuição e outros operadores de que pode precisar usar, como == Assim quando aparecer uma expressão dessas o compilador gera o código correto e o programa continua. Um exemplo para o operador = const MeuVetor& operator= (const MeuVetor& original) { cout << " ===== Atribuicao x = x1: vetor com " << original.quantos << " valores e delta = " << original.delta << endl; if (vetor != NULL) { // ja tinha um vetor aqui então libera antes de alocar o novo cout << " vetor com " << quantos << " elementos sera substituido por vetor com " << original.quantos << " elementos " << endl; delete[] vetor; } // agora copia mesmo quantos = original.quantos; delta = original.delta; vetor = new float[quantos]; /* criado. Agora copia os valores */ for (int i = 0; i < quantos; i++) { vetor[i] = original.vetor[i]; } // end for return *this; } // end operator+() Nada especial mas é bem poderoso você poder fazer isso. Redefinindo os operadores você pode usar soma, divisão, incremento, qualquer coisa com suas classes e rodar o código como você precisa. Imagine uma classe trem composta de classes vagao. Você pode somar um vagao ao trem, mas precisa somar o peso do vagao ao trem, alocar o numero do vagao no descritivo da composição, aumentar o peso e a capacidade de carga, sei lá. Muitos processos podem estar incluídos num simples comando v = v1 + v2 + v3; por exemplo. E TODO o código contido seguramente no método que implementa o operador, para cada operador. Note que quando você escreve v3 = v1; no nosso caso, v3 provavelmente já contem um vetor de dados e a gente precisa liberar essa memória antes de prosseguir. Uma outro comodidade comum para programas de teste: redefinir << Escrevemos uma função Mostra() e usamos assim: cout << endl << "Mostrando v1" << endl; v1.Mostra(); E vemos na tela Mostrando v(5,1.5) ---------- Vetor com 5 valores. Delta = 1.5 Pos: 0 Valor: 0 Pos: 1 Valor: 1.5 Pos: 2 Valor: 3 Pos: 3 Valor: 4.5 Pos: 4 Valor: 6 Um pouco chato. Não seria perfeito poder usar cout << v1 << endl; e já imprimir como a gente quer? Para esses milhões de programas de teste que se escreve nesses cursos de introdução vale a pena porque agiliza os testes, não? E como seria isso? Pensando bem, cout é declarada como ostream em std. Então se eu escrever algo assim na classe MeuVetor redefinindo o operador << para quando eu tiver algo assim ostream << MeuVetor o compilador vai fazer como fez no caso do operador = e chamar a rotina certa, e não precisamos mais da função Mostra(). E podemos escrever todo tipo de teste lá naquela função. Seria algo assim a declaração: ostream& operator << ( ostream& destino, const MeuVetor& v) E aí quando aparecer algo como cout << MeuVetorPreferido o compilador vai ver que std::cout é uma ostream e MeuVetorPreferido é da classe MeuVetor e vai chamar nosso método esperto que podia ser assim escrito // // redefinindo o operador << para essa classe ai podemos // usar cout << vetor que funciona: nada mal // friend ostream& operator << ( ostream& destino, const MeuVetor& v) { destino << endl << "----------\n" << "Vetor com " << v.quantos << " valores. Delta = " << v.delta << endl; for (int i = 0; i < v.quantos; i++) { destino << "Pos: " << i << " Valor: " << v.vetor[i] << endl; } // end for return destino; } // end operator<< E chamar assim: MeuVetor v(5, 1.5); cout << endl << "Mostrando v(5,1.5)" << endl; v.Mostra(); cout << endl << "(*) Mostrando v(5,1.5)" << v << endl; E vai imprimir +++++ Construtor: construindo vetor com 5 valores e delta = 1.5 Mostrando v(5,1.5) ---------- Vetor com 5 valores. Delta = 1.5 Pos: 0 Valor: 0 Pos: 1 Valor: 1.5 Pos: 2 Valor: 3 Pos: 3 Valor: 4.5 Pos: 4 Valor: 6 (*) Mostrando v(5,1.5) ---------- Vetor com 5 valores. Delta = 1.5 Pos: 0 Valor: 0 Pos: 1 Valor: 1.5 Pos: 2 Valor: 3 Pos: 3 Valor: 4.5 Pos: 4 Valor: 6 Então não precisa usar mais v.Mostra() e podemos escrever direto cout << v Se alguém teve paciência de ler até aqui uma última nota: essa sintaxe pode parecer mágica mas é muito poderosa. Num segundo momento ao ler a declaração ela de fato faz sentido. E pode gerar programas muito poderosos e simples de ler, porque a = a - b por exemplo pode funcionar para classes muito complexas e encapsular num simples ato de subtrair uma variável de outra um processo administrativo complexo por exemplo. Vamos programar O programa de teste pode ser copiado aqui: https://github.com/ARFNetoOnCPP/VetorNoForum C++ é uma linguagem enorme e gera programas muito rápidos. Mas com o poder vem a responsabilidade -
C++ Gerar vetor em um main através da classe em arquivo de cabeçalho
arfneto respondeu ao tópico de Thiago1101 em C/C#/C++
Esqueci de comentar isso: O título do tópico, sim... Não faz sentido nem tem a ver com seu problema tampouco. Um arquivo de cabeçalho não é algo assim ativo, é apenas uma maneira de antecipar as declarações para o compilador, já que em muitos casos o código de classes está em arquivos separados e podem estar já compilados, então você precisa de um arquivo contendo apenas as declarações para orientar a compilação. E como eu disse, gerar um vetor em main--- ou em qualquer outra função no programa --- é apenas uma questão de declarar o que se chama uma instância da variável. Isso faz o compilador localizar o construtor correto se declarado, ou um construtor padrão se nenhum construtor for encontrado, e executá-lo. É convencional gerar as classes públicas em arquivos separados, e criar um arquivo de cabeçalhos com as declarações e incluir nos lugares apropriados usando #include -
C++ Gerar vetor em um main através da classe em arquivo de cabeçalho
arfneto respondeu ao tópico de Thiago1101 em C/C#/C++
Muito bem! Esqueci de citar mas acho que já sabe agora: dentro de cada instância do MeuVetor você tem os valores, de modo que se que se você tem lá MeuVetor x(10, 3.0); MeuVetor y(20, 0.5); Pode acessar o conteúdo assim: float valor = x.vetor[2]; y.vetor[0]=0; int quantosX = x.quantos; float deltaY = y.delta; y.Mostra(); Coisas assim. Espero que tenha entendido o caso do construtor de cópia e como e porque ele funciona. E a necessidade do destrutor para liberar a memória. É essencial que entenda essas coisas para programar com objetos. -
C++ Gerar vetor em um main através da classe em arquivo de cabeçalho
arfneto respondeu ao tópico de Thiago1101 em C/C#/C++
Colocando o vetor dentro do objeto Isso você faz simplesmente declarando DeclararVetor x1 = x; Está errado. DeclararVetor é uma classe. E tem um construtor para criar os objetos MeuVetor, chamadas instâncias. A simples declaração já salva tudo. Você só precisa escrever o construtor direito Vou explicar melhor e deixar um exemplo completo, porque acho que esse é um tema importante. Seu programa tem um pé em C e outro em C++ mas está longe ainda da orientação a objetos, então leva pouca vantagem ao usar C++ e não C. Veja com paciência Este seu problema é um bom exemplo para quem está começando a usar uma linguagem orientada a objeto acompanhar, e talvez tenha te faltado uma introdução mais elaborada justamente a esse conceito de objeto. E o que significa isso para tratar um problema, e criar uma classe que vai ser a abstração do problema usando uma dessas linguagens orientada a objetos. Antes de tudo, note que C não é C++ nem C++ é C. São diferentes animais. Bem diferentes. C++ tem um classe vector em std, std::vector, documentada em http://www.cplusplus.com/reference/vector/vector/ que pode resolver seu problema. C tem uma função em stdlib.h, malloc(), presente também em C++, que pode resolver seu problema, e que você de fato usou em seu programa. Mas em C++ você pode usar new e delete ao invés de malloc e free do C e talvez ache que faz mais sentido. Continue lendo. Usando std::vector ou new você não precisa alocar memória diretamente nem controlar isso. Usando malloc() em C++ você precisa cuidar desses "detalhes" todos. Vou te mostrar uma maneira de criar isso em C++ usando new e delete e espero deixar mais evidente a maneira de tratar isso com a orientação clásssica a objetos. Espero que tenha paciência. Sobre a questão inicial: "como recolher o vetor gerado no construtor?" A resposta é curta: você tem dois parâmetros no seu construtor: float dx e int m e seu vetor tem (m+1) posições e em cada uma temos um float dx. Você "recolhe" os valores apenas declarando os caras, por exemplo: DeclararVetor vetor1(10,3,14159); DeclararVetor vetor2(5,2.0); DeclararVetor ConstrutorNormal(m,dx); Só isso. E você teria vetor1 vetor2 e ConstrutorComum criados, usando os valores passados na declaração. Porque funciona? Porque você escreve o construtor para fazer tudo de acordo, e o compilador se encarrega de chamar o construtor certo na hora certa Sobre esse trecho em seu código: /* Tentando fazer a declaração de x como sendo um vetor (A função DeclararVetor gera um vetor, mas não consigo salvá-la em uma variável do main) */ DeclararVetor x{m,dx}; Não é assim que funciona. Entenda que a função DeclararVetor não gera um vetor própriamente. O que gera uma variável da classe, um DeclararVetor, é a simples declaração: DeclararVetor x1, x2, x3, x4; por exemplo geraria 4 vetores, e se diz que são instâncias da classe DeclararVetor. E já estariam "salvos em main". É como declarar float dx, dy, dz, dt; /* cria 4 float */ E dentro desses objetos x1, x2, x3 e x4 estariam os valores de cada vetor, o tamanho e o delta usado. Esse é o grande valor desse conceito, e se chama encapsulamento na literatura. Acho que já notou que sendo assim DeclararVetor não foi um nome feliz para sua classe, porque o construtor não declara nada. A declaração é que acaba executando o construtor --- se você tiver escrito um. De novo: o construtor não salva o objeto. A declaração faz isso. Só que em geral precisa de um construtor para criar o objeto corretamente. Criar um int ou um float é algo definido. Esses são chamados "tipos primitivos" por isso. Está claro como construir cada um. Para tipos que você define, em geral vai precisar de um ou mais construtores Como salvar os valores calculados em x1 para a variável x? Simples: DeclararVetor x = x1; Essa é a mágica dos objetos. Vou explicar a seguir. Não, não pode. não é assim que funciona. Seu construtor original, para a gente continuar: DeclararVetor::DeclararVetor(int m, float dx) { x1 = (float*)malloc((m + 1) * sizeof(float)); for (int i = 0; i < m + 1; i++) { x1[i + 1] = x1[i] + dx; } } Não temos a descrição do que você está tentando implementar em main() mas vemos aqui que o seu vetor é uma sequência de (m+1) valores do tipo float e que são alocados dinâmicamente. E são da forma a(n+1) = a(n) + b , uma função simples nesse caso. Então criar um vetor desses significa alocar memória para o total de valores float necessários e calcular os caras. Encapsulamento Esse nome chique significa que ao declarar um trem desses, uma variável dessa classe, ela vai conter esse material todo e eventualmente proteger isso. Um objeto deses vai conter um array de float com os valores calculados, assim que eu declarar. E o tamanho. E o delta usado para calcular os caras. Vamos mudar o nome da classe para MeuVetor e você vai ver que faz mais sentido que DeclaraMeuVetor por exemplo. Podia ser assim class MeuVetor { int quantos; float delta; float * valor = NULL; } Só isso? sim. Cada MeuVetor é um objeto, encapsulando um vetor de quantos valores calculados usando o delta dx fornecido. E se declara assim MeuVetor a,b,c,d; Agora a gente precisa dar sentido ao objeto. Se fosse em C seria o caso de alocar memória para ele e criar as funções de acesso e seguir adiante. Em C++ podemos criar os construtores, que serão chamados automaticamente cada vez que um objeto desses for criado. Não é preciso controlar nada. O que eu preciso para construir um objeto desses? O tamanho e o delta. Mas eu posso ter vários construtores, outra gentileza da orientação a objetos do C++ Sobrecarga (overloading) Esse outro nome chique quer dizer que eu posso ter construtores ou funções em C++ que se viram para tratar comandos assim: MeuVetor v1(10, 3.1415); MeuVetor v2(100); MeuVetor v3(20.19); MeuVetor v4; E v1 vai ser o normal como no seu exemplo: 10 valores com dx = 3.1415 v2 vai criar 100 caras com um dx padrão que estabeleceremos como 1.0 v3 vai criar um vetor com tamanho padrão que estabeleceremos como de 10 valores. v4 vai criar um unico valor igual a zero. Isso dá uma ideia do poder desse conceito. Como funciona? Simples: pelo número de parâmetros o compilador determina qual versão do construtor deve usar e a vida segue. Segue depois de você escrever todos os construtores necessários, claro Só vou escrever um proque não acrescenta nada: são apenas funções com o mesmo nome mas parâmetros diferentes. Se você só escrever um, o completo, ok: Se declarar de algum outro modo simplesmente dá erro de compilação e pronto. Eis um possível construtor para essa classe usando os dois parâmetros MeuVetor(int n, float dx) { quantos = n; delta = dx; vetor = new float[n]; vetor[0] = 0; for (int i = 0; i < (quantos-1); i++) { vetor[i + 1] = vetor[i] + delta; } // end for } // end constructor Diferenças em relação ao seu construtor original: alocamos exatamente m valores. E assumimos que o primeiro vale 0. No seu cógido alocava um float a mais e o valor de x1[0] não está explícito. E temos mais uma variável, delta. Note que você pode declarar o construtor dentro da classe. Pode ficar mais fácil de ler . E quando liberar a memória alocada? Note que ao fim do programa o sistema pode cuidar disso, mas e se você declara esses valores dentro de uma função que chama toda hora? Essas instâncias do vetor vão ficando inacessíveis, e assim como em C temos que liberar essa memória. Mas como seria isso em C++? Destruindo uma instância da classe: destrutores em C++ Então... Isso já foi resolvido: quando preciso você pode escrever um destrutor de classe, e o compilador se vira para rodar isso quando um objeto se torna inacessível, por exemplo quando seu programa termina. Como funciona? Você declara como o construtor, mas com um til na frente. E sem parâmetros. Algo assim por exemplo ~MeuVetor() { delete[] vetor; /* eis o que importa: liberar a a memoria alocada quanto da construcao */ } // end destructor E a vida segue. E como copiar um MeuVetor para outro, para eu poder escrever algo como MeuVetor v2 = v1; Seria legal se eu não precisasse fazer nada... E é quase isso. Copiando uma classe mais complexa: o construtor de cópia. Um construtor de cópia, se declarado, é chamado automaticamente quando o compilador vê uma tentativa de copiar um objeto, e tem uma declaração simples assim: MeuVetor( MeuVetor &original) { // codigo necessario para copiar } Eis um construtor que copia um vetor direitinho: MeuVetor(const MeuVetor& original) { quantos = original.quantos; delta = original.delta; vetor = new float[quantos]; /* criado. Agora copia os valores */ for (int i = 0; i < quantos; i++) { vetor[i] = original.vetor[i]; } // end for } // end copy constructor Com o construtor, o destrutor e o construtor de cópia podemos escrever tudo do jeito simples, como se fossem variáveis comuns, tipo int ou float. E o compilador faz tudo rodar na hora certa. Mas MeuVetor é uma classe e pode aprender coisas. Acho que agora já deve ter entendido como isso é poderoso. Podemos implementar mais coisas em nossa classe sem mexer em nada do resto do programa. E enquanto não mexer nos parâmetros podemos recriar nossos construtores e destrutores a qualquer momento, sem mexer nos programas que usam a classe Que tal uma função Mostra() que iria mostrar na tela algo assim para o vetor com 4 valores e dx = 3.14159? ---------- Vetor com 4 valores. Delta = 3.14159 Pos: 0 Valor: 0 Pos: 1 Valor: 3.14159 Pos: 2 Valor: 6.28318 Pos: 3 Valor: 9.42477 Assim eu posso escrever MeuVetor v1(10,3.14159); v1.Mostra(); E já ver na tela o conteúdo. Isso é encapsulamento. Mostra() é um método da classe. Publico, de modo que você pode usar em qualquer lugar. Você pode ter métodos private que só podem ser usados dentro da classe, e muitas vezes é exatamente o que você quer. Isso também se aplica às variáveis: quantos e delta podem ser declarados como private e ninguém pode então mudar esses valores de fora da classe. E pensando bem isso seria bom porque ia dar uma confusão alguem escrever v1.quantos = 300 sem alocar a memória de novo e tal... Uma implementação de Mostra() /* claro que vamos querer ver o que tem dentro */ void Mostra() { cout << endl << "----------\n" << "Vetor com " << quantos << " valores. Delta = " << delta << endl; for (int i = 0; i < quantos; i++) { cout << "Pos: " << i << " Valor: " << vetor[i] << endl; } // end for } }; // end Mostra() Testando isso em main() Um teste óbvio seria declarar uns vetores, copiar, mostra e encerrar, certo? E com umas mensagens para acompanhar. Exemplo de teste em main() cout << "Criando v1 com 4 valores e delta = 3.14159" << endl; MeuVetor v1(4, 3.14159); cout << "Criando v2 com 3 valores e delta = 2.0" << endl; MeuVetor v2(3, 2.0); cout << "copiando v1 em v3" << endl; MeuVetor v3 = v1; cout << "copiando v2 em v4" << endl; MeuVetor v4 = v2; cout << endl << "Mostrando v1" << endl; v1.Mostra(); cout << endl << "Mostrando v2" << endl; v2.Mostra(); cout << endl << "Mostrando v3 = v1" << endl; v3.Mostra(); cout << endl << "Mostrando v2 = v4" << endl; v4.Mostra(); Isso deveria gerar algo assim Criando v1 com 4 valores e delta = 3.14159 +++++ Construtor: construindo vetor com 4 valores e delta = 3.14159 Criando v2 com 3 valores e delta = 2.0 +++++ Construtor: construindo vetor com 3 valores e delta = 2 copiando v1 em v3 copia Construindo uma copia: copiando vetor com 4 valores e delta = 3.14159 copiando v2 em v4 copia Construindo uma copia: copiando vetor com 3 valores e delta = 2 Mostrando v1 ---------- Vetor com 4 valores. Delta = 3.14159 Pos: 0 Valor: 0 Pos: 1 Valor: 3.14159 Pos: 2 Valor: 6.28318 Pos: 3 Valor: 9.42477 Mostrando v2 ---------- Vetor com 3 valores. Delta = 2 Pos: 0 Valor: 0 Pos: 1 Valor: 2 Pos: 2 Valor: 4 Mostrando v3 = v1 ---------- Vetor com 4 valores. Delta = 3.14159 Pos: 0 Valor: 0 Pos: 1 Valor: 3.14159 Pos: 2 Valor: 6.28318 Pos: 3 Valor: 9.42477 Mostrando v2 = v4 ---------- Vetor com 3 valores. Delta = 2 Pos: 0 Valor: 0 Pos: 1 Valor: 2 Pos: 2 Valor: 4 C:\Users\toninho\source\repos\OVetor\Debug\OVetor.exe (process 6812) exited with code 0. Press any key to close this window . . . Só tenho esse compilador. Não sei o que você usa. Mas essa é a saída do MicroSoft Visual Studio Community 2019, grátis. Eis o código da classe, com o programa de teste também. Acho que vai entender as diferenças. Coloquei vários cout, equivalentes aos printf do C para você ver na tela o que está acontecendo Em caso de não entender... escreva de novo O programa completo #include <iostream> #include <stdlib.h> using namespace std; class MeuVetor { public: int quantos; float delta; float * vetor = NULL; /* na construcao do objeto vai ser alocado o tamanho correto */ /* construtor com dois parametros */ MeuVetor(int n, float dx) { cout << " +++++ Construtor: construindo vetor com " << n << " valores e delta = " << dx << endl; quantos = n; delta = dx; vetor = new float[n]; vetor[0] = 0; for (int i = 0; i < (quantos-1); i++) { vetor[i + 1] = vetor[i] + delta; } // end for } // end constructor /* destrutor nao tem parametros */ ~MeuVetor() { cout << " ----- Destrutor: fim da vida para um vetor com " << quantos << " valores e delta = " << delta << endl; delete[] vetor; /* eis o que importa: liberar a a memoria alocada quanto da construcao */ } // end destructor /* construtor de copia: essencial porque precisa alocar memoria e copiar tudo */ MeuVetor(const MeuVetor& original) { cout << " copia Construindo uma copia: copiando vetor com " << original.quantos << " valores e delta = " << original.delta << endl; quantos = original.quantos; delta = original.delta; vetor = new float[quantos]; /* criado. Agora copia os valores */ for (int i = 0; i < quantos; i++) { vetor[i] = original.vetor[i]; } // end for } // end copy constructor /* claro que vamos querer ver o que tem dentro */ void Mostra() { cout << endl << "----------\n" << "Vetor com " << quantos << " valores. Delta = " << delta << endl; for (int i = 0; i < quantos; i++) { cout << "Pos: " << i << " Valor: " << vetor[i] << endl; } // end for } }; // end Mostra() int main() { cout << "Criando v1 com 4 valores e delta = 3.14159" << endl; MeuVetor v1(4, 3.14159); cout << "Criando v2 com 3 valores e delta = 2.0" << endl; MeuVetor v2(3, 2.0); cout << "copiando v1 em v3" << endl; MeuVetor v3 = v1; cout << "copiando v2 em v4" << endl; MeuVetor v4 = v2; cout << endl << "Mostrando v1" << endl; v1.Mostra(); cout << endl << "Mostrando v2" << endl; v2.Mostra(); cout << endl << "Mostrando v3 = v1" << endl; v3.Mostra(); cout << endl << "Mostrando v2 = v4" << endl; v4.Mostra(); exit(0); // fim } É isso. -
Meu irmão está derrubando minha internet!
arfneto respondeu ao tópico de Caetano Dias em Redes e Internet
Olá! Se você tem acesso ao suporte da VIVO ligue lá e explique sua suspeita e sua necessidade. Meu modelo não tem essa opção, ao que paarece. Me disseram que talvez usando o usuário support ao invés de admin eu teria acesso a essas configurações, mas no meu modelo não funcionou. Talvez no seu. Pode tentar -
Olá Vou deixar um solução aqui em C com uns palpites pessoais para quem está começando a programar e tem uma lista de problemas/programas como esse aqui. Isso pode ser útil como método de se aproximar de uma solução. É apenas uma possível maneira, relativamente segura. Sequer vou dizer que é boa. Então... Primeiro, evite fazer mais do que está escrito. Mas nunca menos. Considere cada linha como importante. Quase sempre o autor tem uma pegadinha. Pegadinha Nesse caso aqui, a primeira é a maneira de ler os valores: todo mudo tende a programar lendo o valor como inteiro, basta ver os códigos apresentados aqui. Mas o enunciado diz que você pode ter um número V entre 1 e 10E100, muito mais do que cabe em um int então via dar m. se usar um int ou bigint ou sei lá. Pegadinha O enunciado diz que a entrada contem uma linha com o total de testes entre 1 e 1000 seguido de ... Uma linha para cada teste. Não fala em um programa interativo, em que o usuário fica digitando os valores um a um. Mas em geral as pessoas supõem sempre um programa interativo. Mais uma vez, basta ver os códigos propostos acima, em C ou java Tudo bem, só que quando você está testando o programa é um porre ter que redigitar cada teste e ficar esperando os valores e testando de novo e tal. Demora muito e é ruim de reproduzir até dar certo se a gente erra muito Mesmo que seja para ser interativo, faça seus programas lendo de um arquivo para não perder tanto tempo testando, e depois coloque a parte interativa. Crie o arquivo de teste bem simples na própria pasta do programa e vai ver a diferença. Conforme vai progredindo com o programa crie mais arquivos de teste com valores mais complexos ou condições limite. Formato de Entrada Imagine um óbvio arquivo chamado entrada.txt com esse conteúdo: 3 115380 2819311 23456 Nada mal, certo? Direto do enunciado. Enquanto não der o resultado que está lá no enunciado, podemos usar só esse, Talvez com um painel de teste só, certo? É só editar mesmo Formato de Saída Bem simples, não tem sequer o valor lido. Mas não serve durante os testes: vamos querer saber o valor lido e mais algumas coisas. Imprima mais e depois retire quando estiver seguro. calcular_leds() Está lá escrito lá que o programa tem que ter uma função com esse nome e objetivo. Nem pense em escrever sem isso porque vai perder muitos pontos mesmo que funcione. E nem teste se não tiver isso porque vai perder seu tempo. Use os dígitos que estão lá e conte os segmentos acesos, como foi feito nos códigos sugeridos. Pode escrever algo assim E chamando isso para cada dígito do valor a ser aceso tem o total de leds que precisa acender. E para o número todo? Se existisse e funcionasse uma função int total_de_LEDs(char V[ ], int n) onde n é o número de dígitos e V, como diz no enunciado, é o valor a ser aceso no painel, seria só ler o valor N de testes e depois um loop de N vezes chamando essa função e imprimindo o valor retornado e pronto, não é? É. Veja uma possível função dessas: Duas notas: A declaração de V como char V[] é segura porque deixa a alocação de memória a cargo de quem chamou a função. E nem precisamos testar o tamanho do painel V porque o cara que chamou já enviou o tamanho n como parâmetro. Assim você transfere a responsabilidade. A beleza dos programas de teste e de curso: não precisa testar quase nada que não esteja lá no enunciado. A menos que seja melhor pra quem está programando... A linha V - '0' --- Esse é um caso similar a função calcula_leds() --- os valores sendo lidos como texto permitem que você digite direto no arquivo texto o valor que quer testar, um valor por linha. E deixam você livre de usar matemática como dividir por 10 pra ir pegando os dígitos um a um se leu um int, o que seria de todo modo errado como já foi visto. Mas então o zero será '0' e nove será '9' e os valores estarão entre 48 e 57, os códigos desses valores na tabela. Veja em uma tabela ASCII online Etão basta subtrair o valor de zero, '0' no caso e vai ter o número decimal... A beleza dos programas de teste e de curso: não precisa testar quase nada que não esteja lá no enunciado ou que seja melhor pra quem está programando... Então não precisa testar se vieram letras por exemplo. Ou se o arquivo não existe, ou... E como costura isso? Algo assim quase resolve: Abre o arquivo entrada.txt, que pode ser inicialmente o descrito no enunciado, e chama a função que a gente escreveu para cada painel V lido do arquivo, e imprime o total como pedido. Nada mal. A funçao strlen() devolve o número de dígitos no valor que foi lido do arquivo. char V[200] aloca a memória necessária para ler os dados do arquivo. Vai mostrar o resultado certo, mas nesse caso alguma coisa temos que testar: o enunciado limita o número N de soluções e o tamanho de cada painel V a ser aceso. Então não testar não é opção. Vamos incluir os testes então... Não aumentou muito: é preciso testar os limites de N e V, está escrito lá. E tem um teste a mais porque se ao tentar ler um item não vier nada é melhor para o programa parar por aí mesmo. Nota: exit() é a função clássica para encerrar o programa imediatamente. exit(0) em geral se usa para indicar sucesso e qualquer outro valor para erro. O resultado: para a entrada prevista Espero que ajude alguém... Não são meus alunos, penso. Não sou o professor, já se passaram vários dias desde que o tópico foi aberto então acho que não é tão errado postar ao final uma possível solução // meu compilador reclama de tudo em C sem essa linha. ignore se nao usa VISUAL STUDIO 2019 // nao tenho tempo para instalar um outro mais gentil com codigo em C #define _CRT_SECURE_NO_WARNINGS #include "stdio.h" #include "stdlib.h" #include "string.h" int calcular_leds(int digito) { int led[10] = { 6, 2, 5, 5, 4, 5, 6, 3, 7, 6 }; return led[digito]; } // end calcular_leds() int total_de_LEDs(char V[], int n) { int digito; int soma = 0; for (int i = 0; i < n; i++) { digito = V[i] - '0'; soma = soma + calcular_leds(digito); } // end for return soma; } // end total_de_LEDs() int main(int argc, char** argv) { int i; int c; int N; char* arquivo = "entrada.txt"; char V[200]; FILE* Entrada; Entrada = fopen(arquivo, "r"); c = fscanf(Entrada, "%d", &N); if ((N < 1) || (N > 1000)) { printf("N = %d: fora dos limites\n", N); exit(1); } for (i = 1; i <= N; i++) { c = fscanf(Entrada, "%s", V); // tenta ler um unico item. fscanf deve retornar 1 if (c != 1) { printf("Nao leu nada. Encerrando.\n"); exit(1); // cancela } // Entao leu alguma coisa c = strlen(V); // c passa a ter o numero de digitos de V, o painel de teste // se nao tiver entre 1 e 100 digitos, cancela com exit() if ((c < 1) || (c > 100)) { printf("V = %d. Fora do especificado: ( 1<=V<=100). Encerrando.\n", c); exit(1); } // leu painel V com c digitos, faz o teste c = total_de_LEDs(V, c); printf("%d leds\n", c); } // end for exit(0); // 0 = ok. podia ser return 0, claro, ja que ao retornar de main encerra mesmo } // end main()
-
Olá! provavelmente você copiou o trecho de código de uma tela como a do navegador do forum para o editor e aí acabou inserindo uns caracteres estranhos... Experimente redigitar uma linha dessas e deve ver que o erro some..
-
Mesmo em java não está certo... Pois é.. Não tem a função. E não pode usar um int para ler o valor V dos N testes: podem ser até 1000 testes, mas o painel tem entre 1 e CEM dígitos: não cabe em um int. deve usar bigdecimal ou usar strings... Mesmo caso em C Veja: É um jeito chique de dizer que o painel de LEDs tem até 100 dígitos. E uma pegadinha pra tomar uns pontos de todo aluno que usar um inteiro para ler os valores, em java, em C ou COBOL . O maior valor inteiro não dá nem 10 dígitos, certo? Ficam faltando ... noventa
-
Olá! Ainda acho que o fornecedor do sistema de monitoramento é que tinha que colocar um segundo endereço de "escuta" no serviço de conexão, porque é um caso comum. Uma outra possibilidade é usar aparelhos distintos para acesso na rede local, como um celular ou um tablet com wifi De volta ao DNS suponha que sua rede esteja registrada em algum serviço de registro dinâmico, tipo no-ip ou dyndns, como companiaXYZ.dyndns.net. dyndns.net é um domínio controlado por no-ip, por exemplo. Você não pode acessar esse domínio de dentro de sua rede porque criaria um loop de roteamento. Mas se você pegar um computador qualquer e rodar um servidor DNS nele, Windows Server rodando microsoft dns ou linux rodando bind por exemplo, e configurar esse micro como dono do mesmo domínio dyndns.net ele resolve o endereço da maquina \\cameras para o endereço local correto e voce pode acessar na rede privada. E na rede publica vai continuar ok. E para qualquer outro domínio seu servidor DNS vai usar o gateway padrão dele, seu roteador principal, e aí fica tudo certo. Seu servidor DHCP claro vai passar a dar esse endereço como o primeiro servidor DNS da lista, e assim se fecha o circulo: via wifi na rede local os dispositivos recebem o endereço do seu servidor DNS normalmente, a partir do servidor DHCP. E qualquer acesso a dyndns.net será resolvido para os endereços na rede local. Outros acessos cotinuam seu caminho de resolução. A partir de outras redes continua valendo claro o registro de dyndns.net em no-ip e você continua acessando as cameras. E não há conflito.
-
Acho que unifi é o nome escolhido pela ubiquiti pasta chamar a linha de rede mesh da empresa
-
Olá! Vou imaginar os elevadores no lado norte para simplificar Os elevadores seriam o grande obstáculo estrutural para bloquear os sinais de wifi, mas como estão do outro lado ficam apenas as vigas estruturais se for o caso. No desenho não estão identificáveis, ao menos para mim. Então o sinal deve se propagar bem. Se usar mesh vai ter boa estabilidade e performance, mas com um custo muito mais alto. Em relação aos cabos, considere o posicionamento dos caras, dos switches e tal. Se for usar um único ponto de distribuição TODOS os cabos vão ter que ter rota até lá. Mas se usar 2x24 pode usar um switch na sala de produção no oeste e um outro no leste, possivelmente simplificando muito o serviço de cabeamento se não foi feito ainda... Em relação ao wifi, a política recomenda uma rede wifi distinta e quem sabe um switch atendendo o lado sul, onde estão as salas de reuniões e a sala da dra. Isolando essa área de atividades de produção e pesquisa por exemplo. Uma necessidade qualquer de mudança nessas redes bem na hora que tem uma reunião especialmente importante e você sabe o que acontece: caem as conexões na sala de reuniões no meio de uma apresentação e diretores saem com armas em punho.... Uma rede do lado norte na recepção com tráfego segregado também é opção saudável. E alguns pontos Ethernet para aqueles micros tipo quiosque mostrando apresentações e pelo menos dois pontos na mesa da recepcionista, porque pode precisar de acesso a algum sistema de segurança e comunicação com prioridade, afinal é a primeira barreira no escritório. Minha recomendação grátis inclui fortemente redes distintas para produção, diretoria, segurança, marketing e tal. E servidores DHCP distintos para ter um mínimo de redundância. Se o único servidor DHCP naquele super roteador XYZ recomendado e caro para, fica tudo no escuro sem necessidade. Se um funcionário ou consultor meu recomendar isso numa rede onde tem uma sala de produção, ou salas de pesquisas, ou emissão de notas fiscais, vou jogar algo na cabeça dele. Algo pesado, quando ele estiver saindo para procurar outro trabalho. Minha opinião, no entanto. Sei que não é compartilhada por muitos. e reuniões. Mas eu esperaria um plano de contingência para as falhas mais óbvias. E a eliminação de óbvios pontos únicos de falha, gargalos... E acessos alternativos a internet, com o pessoal sabendo exatamente como proceder em caso de falha, nem que tenha que se contentar com um roteador 4G na sala de produção quando tudo mais parou... Boa sorte
-
Setup rede de internet em casa de 3 andares
arfneto respondeu ao tópico de NathanJFV em Redes e Internet
Olá! Assim já funcionaria, mas o ideal seria usar esse fio que vai do terceiro para o segundo andar e descer até o primeiro --- em muitos casos o duto continua descendo --- e cortar no segundo, ficando com dois cabos, 1-2 e 1-3. Em geral é a topologia que a gente procura conseguir: os roteadores do primeiro nível ligados diretamente ao gateway padrão, que sai para a rede pública. -
Meu irmão está derrubando minha internet!
arfneto respondeu ao tópico de Caetano Dias em Redes e Internet
Olá! Tenho um aparelho da vivo, mas outro modelo, RTF3507VW-N1 da marca Askey, e não tem assim muitas opções de controle. Algumas configurações você póde ver mesmo sem senha, mas para poder alterar algo você precisa ter a senha de acesso. Seu irmão tem essa senha e você não? O que significa " derrubar a internet" ? O que acontece que faz você suspeitar de seu irmão? Está seguro de que tenha esse lance de abrir um link nessa página 'padrão'? onde viu isso? Em geral esses roteadores tem um servidor web modesto que atende uma única página, a do endereço LAN dele. E alguns nessa tela tem a opção de um usuário comum e um usuário admin. Não é o caso do meu roteador da VIVO, por exemplo, mas há outros que tem. No meu caso basta tentar abrir algo nas telas de gerenciamento que vem a janela pedindo a senha. -
Olá! Não é exatamente um erro a ser corrigido. É assim que -- não --- funciona, até onde eu sei. Isso seria um loop de redirecionamento e não sei se os roteadores tem como tratar isso. Seu acesso à sua própria rede tentaria "sair" pelo roteador para o gateway público de sua WAN, mas teria que parar no roteador, porque seria o endereço dele. E aí teria que entrar de volta pela tabela de encaminhamento de portas para o servidor das câmeras e chegar até o destino. E voltar para o aparelho onde está rodando o monitoramento, que nesse momento está em sua rede local. E tem o NAT, o protocolo de mascaramento do endereço privado no roteador, para trazer as respostas para seu aparelho. Quem devia resolver isso era exatamente o software de monitoramento, permitindo a configuração de dois endereços, um público e outro privado. Trivial. É o mesmo que acontece com telefonia VOIP quando o aparelho está na rede local tem que ter outro endereço, até onde eu sei. Se precisa mesmo de uma solução sem envolver o fornecedor, talvez possa simplesmente rodar um servidor DNS na sua rede local e mapear o endereço público registrado para seu roteador para o endereço do servidor das câmeras na rede local. E usar esse servidor nas configurações de seus servidores DHCP, claro.
-
Maquinas em redes diferentes se comunicando
arfneto respondeu ao tópico de Wagner Guilger Correa em Redes e Internet
Olá! Se as máquinas estão em redes físicamente distintas e vai conectar pela internet precisa programar os roteadores intermediários para encaminhar os pacotes, ou criar uma VPN e conectar através dela. Uma solução rápida seria usar o Hamachi da LogMeIn, grátis para até 5 máquinas e praticamente sem configuração, ou OpenVPN. Se é apenas um banco de dados, registre o roteador do servidor dinâmicamente por exemplo em DYNDNS ou NO-IP, e encaminhe o tráfego da porta que vai usar para o banco de dados para o endereço do servidor na rede local dele. E acesse o banco usando http://endereco-registrado:porta -
Provavelmente fez bem você em não insistir no trabalho tendo apenas 2 dias pra terminar e com toda a dificuldade. De todo modo, vou postar o que seria meu palpite. Pode ser útil pra você entender o que acontecia, se voltar a isso, ou pode ajudar alguém interessado nessas coisas ou pensando em implementar uma versão de campo minado Essas funções são só uma prova de conceito, para ajudar a implementar o jogo. Pequenas partes que pode testar em separado. Imagine seu tabuleiro declarado assim: Você controla o tamanho em uso através dos valores que leu do usuário no início do programa, m linhas por n colunas com z minas, mas declara o tabuleiro com o tamanho máximo, que não é assim tão grande afinal. Os valores estranhos que viu em seu programa podem ser devidos a você não ter inicializado o tabuleiro com nada conhecido, e o seu compilador não inicializar talvez com zero automaticamente. Para imprimir, pode pensar em uma função como essa abaixo, que só mostra as células em uma --- talvez muito longa --- linha por vez, mostra() Note que se quer por exemplo colocar um valor conhecido nas células para ajudar a testar e formatar os campos, pode usar algo como essa mínima função numera() Na hora de colocar as minas no tabuleiro, pode usar algo como essa rotina poe_as_minas() aqui, que usa a ideia que expliquei em detalhe num post anterior, como deve ter visto. @isrnick aqui disse que essa lógica que eu expliquei no outro post tem até um nome! Nunca pensei nisso, porque é uma coisa tão ingênua... Mas sei como o mundo acadêmico é cheio disso e os caras querem o crédito de tudo. Eu não teria coragem de reivindicar a ideia de algo tão besta, ou mesmo por meu nome: você tem um certo número de minas pra colocar e um certo número de posições livres no tabuleiro. Então sorteia uma posição. Vai no tabuleiro e conta de um em um a partir do início, mas tomando o óbvio cuidado de pular as células vazias. Eu uso isso desde moleque quando (tentava) simular jogos de cartas. Só isso. Claro, o método de Knuth/Fisher/Yates não tem esse lance de pular posições ocupadas. É só a maneira de sortear as coisas. Podia chamar isso aqui de Knuth/Fisher/Yates/arfneto Ok essa foi pobre. De volta ao tópico Essa é uma possível implementação. Tem apenas um loop para colocar as minas e uns ajustes pra pular as células que já tenham uma mina. Não é nada autoritativo, devem haver por certo melhores maneiras de fazer isso. E piores. Mas essa funciona com um número mínimo de operações. A função auxiliar que avança os índices está a seguir. Bem simples, deixei fora para facilitar o entendimento do loop. @isrnick Se conhecia esse método ou teve essa ideia, não entendo como sugere implementar com um vetor auxiliar e um novo nível de índices. Devo ter perdido algo Imagino que tenha explicado isso no meio desse tópico antigo de 2018, e não aqui onde o autor do tópico poderia acessar de imediato. De todo modo ao embaralhar todo o vetor em um outro vai "sortear" 8099 casas para 8100 valores, no caso de 90x90. Sabendo, como você diz, que não é preciso. Para colocar 200 minas, 8099 sorteios. Para 4 minas, 8099 sorteios... Mesmo sabendo que bastariam n sorteios para n minas, como você disse. E quanto à facilidade de entender a lógica, tenho também dúvida: ao invés de ir lá sortear 4 vezes para 4 minas, vai usar 8099 veze o sorteio para criar uma outra estrutura, como um outro tabuleiro ou vetor como disse, e aí nesse outro tabuleiro pegar as posições das 4 minas, como sugeriu. E o aluno, ou o autor do tópico aqui, vai ter que entender um segundo nível de índices, porque a posição da mina não vai ser a posição tabuleiro[j] mas sim a posição tabuleiro[ coisa ] [ coisa[j] ] já que vai ter que declarar essa coisa para poder reordenar. E nem é necessário: você pode muito bem fazer essa reordenação no próprio tabuleiro, usando o mesmo método cujo nome citou, e a lógica que eu expliquei uns posts atrás. Isso porque a cada embaralhamento o número de células livres diminui e então pode ir extraindo as novas posições e colocando no início, já que elas não serão revisitadas pelo algoritmo... No caso desse jogo não faria sentido, porque eu não vejo razão para reordenar todas as células m*n sabendo que só precisa de z. E note que nesse caso z<15 por definição. Pense nisso. Dependendo de sua experiência com essas coisas, creio que não terá dificuldade em implementar o que alguém chamaria de inline shuffling nesse tabuleiro. Acho que pode ser útil para muitos essa implementação. Se quiser pode abrir um tópico e deixamos aqui para o pessoal. Sem nossos nomes @Daniela Calfat Maldaun Eis como seria um programa principal pra rodar isso, depois de ler os valores na tela: printf("\nBem vindo ao Caça-Minas!\n"); printf("\n=======================================\n"); printf("Eis a tabela como veio ao mundo:\n"); mostra(); numera(); printf("\n=======================================\n"); printf("Agora numerando as celulas:\n"); mostra(); // agora vamos testar isso com um exemplo srand(seed); printf("\nIniciou o gerador com a semente %d, como pedido\n", seed); printf("Agora vai colocar as %d minas no tabuleiro de %d x %d\n", z, m, n); poe_as_minas(); printf("\n=======================================\n"); printf("Agora com -1 onde esao as minas:\n"); mostra(); E um exemplo da tela: Boa sorte! Continue programando!
-
C++ Procedimento que retira os valores múltiplos de 3 da pilha
arfneto respondeu ao tópico de Leonardo Naressi em C/C#/C++
Wow é gente pra caramba pra ler sobre estruturas e dados -
leia esse com atencao. E quase igual // // em uso estão mxn celulas apenas // for (i = 0; i < m; i++) { // m linhas for (j = 0; j < n; j++) { // colunas tabuleiro[i][j] = j + 10 * i; // pra saber o que esperar } } // gravou um tabuleiro de teste // agora mostra for (i = 0; i < m; i++) { // m linhas for ( j = 0; j < n; j++) { // imprime [m][n] printf("%4i ", tabuleiro[i][j]); } printf("\n)"); } Vai imprimir assim: Entende o que quero dizer como preencher com algo conhecido pra ver se está indo ok? adicionado 28 minutos depois @isrnick Essa é uma pegadinha clássica. Acho que o que se procura nesse exercício é ver se o aluno resiste à tentação de implementar sem pensar. Com esse número máximo de minas e os computadores de hoje em dia, vai ser zero eficiente mas vai levar uns segundos a mais talvez. Mas você tem razão: não é esperto fazer assim. Essa situação é comum nos jogos de cartas para embaralhar antes de dar cartas de novo. Um procedimento eficiente e seguro: imagine que você tem que colocar as 8099 minas em um tabuleiro de 8100 como falou: quando for colocar a ultima terá duas posições vazias e terá que escolher uma delas para colocar a última mina. Mas no início terá 8100 casinhas livres para colocar sua próxima mina... Então como preencher o tabuleiro com exatas 8099 chamadas a rand()? Simples: veja o tabuleiro como uma longa fila de 8100 casinhas: no fundo é isso mesmo, certo? Use rand() e sorteie a posicao da primeira mina. Agora voce tem 8099 possibilidades para colocar a proxima das 8098 minas restantes, certo? entao usa rand() e escolhe uma posicao nova, mas dessa vez entre 1 e 8099, ja que uma mina já está lá. E assim por diante, até restar uma mina e duas casinhas livres. Como colocar a mina no tabuleiro? Simples: pegue a posicao sorteada e conte de um em um a partir da primeira, mas obviamente pulando as posições onde ja tem mina, que nesse caso valem -1, pelo que vi. Acho que entendeu já, mas na prática: você usa um loop variando o total de minas a colocar. No inicio tem as z minas do enunciado. a cada passo no loop voce escolhe 1 mina entre as posições restantes, que serao o tamanho do tabuleiro menos o total de minas que ja estão la. E aí cola ela na posicao sorteada, pulando as celulas que ja tem minas. Assim garante matematicamente o total de chamadas a rand() e evita a degradação dos tempos de execução conforme o tabuleiro vai ficando cheio... O total de "sorteios" fica constante: igual ao numero de minas, z
-
Sim. No seu teste, coloque um valor fixo para as celulas do tabuleiro, para saber ideia se vai imprimir ok depois, algo como 10 * linha + coluna. E use um espaço depois onde imprime tabuleiro[m][n] para não ficar tudo grudado. E esta salvando m e n para depois usar como indice no for. Porque nao escrever direto usando os indices i e j por exemplo?
-
Declare o tabuleiro com o tamanho maximo mesmo. No seu código você controla o que o sujeito digitou. 90x90 nem é grande assim.
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