NOVINKA - Online rekvalifikační kurz Java programátor. Oblíbená a studenty ověřená rekvalifikace - nyní i online.
NOVINKA – Víkendový online kurz Software tester, který tě posune dál. Zjisti, jak na to!

Diskuze: Externí naplnění pole

V předchozím kvízu, Online test znalostí C++, jsme si ověřili nabyté zkušenosti z kurzu.

Aktivity
Avatar
Martin Kobelka:25.9.2016 20:52

Zdravím. Dokázal by mi někdo prosím vysvětlit, proč nejde pole naplnit externě takto?

#include <stdio.h>

void zpracujPole(int *pole[])
{
    int i;
    for(i = 0; i < 4; i++){
        *pole[i] = i + 1;

    }
}

int main(void)
{
    int pole[4];
    zpracujPole(&pole);
    return 0;
}
 
Odpovědět
25.9.2016 20:52
Avatar
strnadrichard:25.9.2016 21:07

No, ačkoliv mé znalosti C++ nejsou nikterak vysoké, tak pokud si dobře pamatuju, tak při předávání pointeru na pole, musíme programu říct, jak je to pole velké.
Tudíž správné předání pole do metody by mělo vypadat nějak takhle:

void zpracujPole(int (*pole)[4])

Tohle pořád neřeší problém uvnitř metody, kdy kvůli rozdílné prioritě operátorů říkáš "První sáhni do pole, vezmi ten prvek, a na jeho adresu zapiš dané číslo".
Ty potřebuješ provést první dereferenci toho pole a až pak přistoupit na jeho prvek.

(*pole)[i] = i + 1;

A tenhle kód by měl fungovat přesně tak jak si představuješ.

Editováno 25.9.2016 21:07
Akceptované řešení
+20 Zkušeností
+2,50 Kč
Řešení problému
 
Nahoru Odpovědět
25.9.2016 21:07
Avatar
Martin Kobelka:25.9.2016 21:13

Díky, problém vyřeše. Nemusel jsem ale zadávat přimo velikost pole. Zde je řešení.

#include <stdio.h>

void zpracujPole(int (*pole)[])
{
    int i;
    for(i = 0; i < 4; i++){
        (*pole)[i] = i + 1;

    }
}

void vypisPole(int pole[], int delka)
{
    int i;
    for(i = 0; i < delka; i++) {
        printf("%d\n", pole[i]);
    }
}

int main(void)
{
    int pole[4];
    zpracujPole(&pole);
    vypisPole(pole, 4);
    return 0;
}
 
Nahoru Odpovědět
25.9.2016 21:13
Avatar
Neaktivní uživatel:26.9.2016 18:04
/* Pole jako argument funkce, zpusob vypisu */

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>
#define SIZE 4

void zpracujPole1(int p[], int vel);
void zpracujPole2(int p[], int vel);
void zpracujPole3(int *p, int vel);
void zpracujPole4(int *p, int vel);
void vypisPole1(int p[], int vel);
void vypisPole2(int p[], int vel);
void vypisPole3(int *p, int vel);
void vypisPole4(int *p, int vel);

int main(int argc, char *argv[]){
        int pole[SIZE];
        zpracujPole1(pole, SIZE);
        zpracujPole2(pole, SIZE);
        zpracujPole3(pole, SIZE);
        zpracujPole4(pole, SIZE);
        vypisPole1(pole, SIZE);
        vypisPole2(pole, SIZE);
        vypisPole3(pole, SIZE);
        vypisPole4(pole, SIZE);
        return 0;
}

// Parametr zadany jako bezrozmerne pole, pole nacteno indexaci ukazatele
void zpracujPole1(int p[], int vel){
        int i;
        for (i = 0; i < vel; i++){
                p[i] = i + 1;
        }
}

// Parametr zadany jako bezrozmerne pole, pole nacteno pomoci ukazatelove aritmetiky
void zpracujPole2(int p[], int vel){
        int i;
        for (i = 0; i < vel; i++){
                *(p + i) = i + 1;
        }
}

// Parametr zadany jako ukazatel, pole nacteno indexaci ukazatele
void zpracujPole3(int *p, int vel){
        int i;
        for (i = 0; i < vel; i++){
                p[i] = i + 1;
        }
}

// Parametr zadany jako ukazatel, pole nacteno pomoci ukazatelove aritmetiky
void zpracujPole4(int *p, int vel){
        int i;
        for (i = 0; i < vel; i++){
                *(p + i) = i + 1;
        }
}

// Vypis pole indexaci ukazatele, argument bezrozmerne pole
void vypisPole1(int p[], int vel){
        int i;
        for (i = 0; i < vel; i++){
                printf("%d\n", p[i]);
        }
}

// Vypis pole pomoci ukazatelove aritmetiky, argument bezrozmerne pole
void vypisPole2(int p[], int vel){
        int i;
        for (i = 0; i < vel; i++){
                printf("%d\n", *(p + i));
        }
}

// Vypis pole indexaci ukazatele, argument ukazatel
void vypisPole3(int *p, int vel){
        int i;
        for (i = 0; i < vel; i++){
                printf("%d\n", p[i]);
        }
}

// Vypis pole pomoci ukazatelove aritmetiky, argument ukazatel
void vypisPole4(int *p, int vel){
        int i;
        for (i = 0; i < vel; i++){
                printf("%d\n", *(p+i));
        }
}

Chyba v prvním příspěvku, proč to nefunguje, je ta, že funkci nepředáváte ukazatel na pole. To co předáváte funkci je totiž pole ukazatelů na typ int, což je něco jiného.

Prototyp funkce ve druhém příspěvku není v pořádku, pole lze předat funkci třemi způsoby:

  1. Zadaný jako pole
  2. Zadaný jako bezrozměrné pole
  3. Zadaný jako ukazatel

Doporučuji 2. a 3. způsob spolu s velikostí pole jako další parametr.

Program ve třetím příspěvku, ač vypisuje očekávaný obsah pole, není syntakticky v pořádku. Takto se pole jako parametr funkci nepředává. Navíc funkce zpracujPole() není obecná, chybí velikost pole a ve funkci jsou tak hodnoty které jsou definovány mimo funkci. Volání funkce zpracujPole() taktéž není v pořádku. To co se předává funkci jako parametr je ukazatel na pole a ukazatel na pole je vždy jméno pole bez indexu. Referenční operátor & tam být nemá. Správné volání a předávání pole a jeho velikosti jako parametru funkci máte ve funkci vypisPole(). Další způsoby předávání pole jako parametru funkci a druhy výpisu, viz. kód.

PS: Ještě jedna drobnost, doporučení. Velikost pole zadávejte jako konstantu pomocí direktivy preprocesoru #define. Vyhnete se tak mnoha nepříjemnostem při ladění větších aplikací.

Nahoru Odpovědět
26.9.2016 18:04
Neaktivní uživatelský účet
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 4 zpráv z 4.