Page 1 of 1

neskaidrība ar sintaksi

Posted: 04 Jan 2013, 00:24
by kristapuciitis
Sveiki!
Lasīju šeit esošo kodu un man radīja neskaidrības dažas vietas:

Code: Select all

struct AdjListNode
{
    int dest;
    int weight;
    struct AdjListNode* next;
};

//...

struct AdjListNode* newAdjListNode(int dest, int weight)
{
    struct AdjListNode* newNode =  (struct AdjListNode*) malloc(sizeof(struct AdjListNode)); 
 // šeit nesaprotu- kāpēc ir struct pirms AdjListNode visās vietās?
    newNode->dest = dest;
    newNode->weight = weight;
    newNode->next = NULL;
    return newNode;
}
Ko tas nozīmē, ja ieliek struct pirms mainīgā tipa, un kāda ir atšķirība, ja to nelieto? (AdjListNode* newNode = ... , kā es to darīju līdz šim) ?

Re: neskaidrība ar sintaksi

Posted: 04 Jan 2013, 00:40
by kovacs
pieļauju ka oriģinālais kods ir raksīts C, kur tā bija jāraksta. Vai tā ir patiesība uz C99/C11 nepateikšu.

C++ tas 99.9% nav nepieciešams, bet varu kļūdīties, jo sen neesmu teoriju atkārtojis. :)

Re: neskaidrība ar sintaksi

Posted: 04 Jan 2013, 11:26
by bubu
struct ir jāraksta struct tipiem C valodā. Tāpat kā enum tipiem jāraksta priekšā enum. Tā tas valodā definēts.
C++ valodā tas nav jāraksta (arī enum'iem). Kompilators gan to atļaus rakstīt savietojamības dēļ ar C kodu - lai tev portējot C kodu uz C++ nebūtu simtiem vietās jādzēš ārā tas struct.

Lai C valodā arī nevajadzētu rakstīt to struct (apnicīgi taču), tam lieto typedef'u:

Code: Select all

typedef struct
{
    ...
} AdjListNode;

void foo()
{
    AdjListNode* newNode = ...
}
struct/enum vajadzība droši vien nāk no tā, ka C valodā tu vari rakstīt šādi:

Code: Select all

struct Foo { int a; int b; } variable;
Ja struct nevajadzētu rakstīt, tad šādu kodu C kompilators nevarētu noparsēt to ar konteksta-brīvu gramatiku (parsējot vārdu "Foo" viņš nezinātu, kas tas ir: enums? struct? Viņam nāktos parsēt tālāk):

Code: Select all

Foo { int a; int b; } variable;

Re: neskaidrība ar sintaksi

Posted: 09 Mar 2013, 22:45
by Arrovs
brīnos ka pamācībās neviens nenodefinē to malloc aptuveni šādi
#define jauns(struktura) sys_malloc(sizeof(struktura))
#define jauni(struktura,daudzums) sys_malloc(daudzums*sizeof(struktura))
Konversijai nekad C īsti neesu redzējis nozīmi, bet to protams var piemest pirms sys_malloc
(struktura*)
Šeit pieņemu, ka struktūras veido ar taipdefu.

Re: neskaidrība ar sintaksi

Posted: 10 Mar 2013, 06:06
by bubu
C valodai kāsti no void* uz T* nav nepieciešami. Tur viss pats kāstojas. C++'am turpretī vajag obligāti kāstot tāpēc, ka tā ir tipu droša valoda un neļaus automātiski pārvērst patvaļīga tipa pointerus. Kas parasti ir labi, jo palīdz noķert kļūdainas situācijas.

Lūk piemērs. Tev ir šāds kods:

Code: Select all

struct A { ... };
struct B { ... };
...
struct A* a = NULL;
struct B* b = NULL;
...
a = malloc(sizeof(struct A));
b = malloc(sizeof(struct B));
...
Un tu izdomā, ka b mainīgajam vajag tomēr būt ar struct A tipu:

Code: Select all

struct A* b = NULL;
Kods joprojām kompilēsies, bet iespējams darīs nelabu lietu runtaimā.
Tāpēc rakstot:

Code: Select all

b = (struct A*)malloc(sizeof(struct B));
tu dabūsi kļūdu kompilēšanas laikā, kas vienmēr ir labi.

Alternatīvi, ja nav jāemulē struct'u mantošana (kā C++'ā), tad var rakstīt šādi:

Code: Select all

b = malloc(sizeof(*b));
Nav nepieciešams kāstot un tas izdalīs precīzi tik atmiņas, cik vajag b mainīgajam, lai arī kāds tips tam nebūtu.

#define if ja
#define else citadi
#define return atgriezt
:)