[C++] Pointer initialisatie met array(unsigned char* = )

Pagina: 1
Acties:

  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Is het mogelijk een pointer (a) zo te initialiseren (vergelijkbaar met b)?
Op deze manier werkt het niet, maar hoe moet het wel?
Uiteidenlijk wil ik een pointer in een struct op deze manier initialiseren of moet ik er dan toch een array van maken?
code:
1
2
3
4
5
6
7
8
#include "stdafx.h"

int main()
{
    char* b = "Tweakers";
    unsigned char* a = {0, 1, 2, 3};
    return 0;
}

  • whoami
  • Registratie: December 2000
  • Laatst online: 19:58
Wat bedoel je precies?

code:
1
char* b = "Bdkdkd";

is geen probleem,

die andere pointer (a), daar moet je
code:
1
unsigned char* a = {'0', '1', '2'};

van maken.

https://fgheysels.github.io/


  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Dat levert op:
code:
1
2
error C2440: 'initializing' : cannot convert from 'const char' to 'unsigned char *'
        Conversion from integral type to pointer type requires reinterpret_cast, C-style cast or function-style cast

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 30-08 23:12
C:
1
const char * p [] = { "Ik", "Ben","Lief" };

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • whoami
  • Registratie: December 2000
  • Laatst online: 19:58
farlane schreef op 25 september 2002 @ 14:59:
C:
1
const char * p [] = { "Ik", "Ben","Lief" };


Dat zijn geen characters maar strings.

https://fgheysels.github.io/


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 30-08 23:12
whoami schreef op 25 september 2002 @ 15:07:
Dat zijn geen characters maar strings.
Hmmm... ik meende dat dat ook was wat Dhr vdSpek wilde bereiken.
( Of ik snap de vraagstelling niet. :) )

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • whoami
  • Registratie: December 2000
  • Laatst online: 19:58
farlane schreef op 25 september 2002 @ 15:13:
[...]


Hmmm... ik meende dat dat ook was wat Dhr vdSpek wilde bereiken.
( Of ik snap de vraagstelling niet. :) )


Als het zo is, dan is het natuurlijk mogelijk zoals jij het zegt.

Of het kan ook zo:
code:
1
char** blaat = { "ik", "ben", "niet", "lief"};


Dacht ik zo....

https://fgheysels.github.io/


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 30-08 23:12
Of zo, maar dan is het geen pointer, wat naar mijn idee niet veel uitmaakt in dat geval:

C:
1
const char a [] = { '1','2','3' };

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Verwijderd

Ik heb het vermoeden dat hij dit bedoelt

C++:
1
2
3
4
5
6
const unsigned char a [] = { 
(unsigned char) 1 , 
(unsigned char) 2 , 
(unsigned char) 3 , 
(unsigned char) 4 
};

  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Wat ik wil is de volgende variable direct initialiseren:
code:
1
unsigned char* a = ...;

Dit is dus een pointer en geen array. Het moet een pointer zijn omdat de lengte variabel moet zijn.

  • .oisyn
  • Registratie: September 2000
  • Nu online

.oisyn

Moderator Devschuur®

Demotivational Speaker

een pointer heeft geen variabele lengte, en als je de array langer wilt maken zul je een nieuwe moeten alloceren, de data moeten kopieren en dan de oude array evt. verwijderen.

Oftewel, als je een dynamische array wilt initializeren zul je een nieuwe moeten alloceren en dan de data moeten kopieren

en je kunt natuurlijk ook gewoon een array aan een pointer assignen
C++:
1
2
int bla[] = { 1, 2, 3, 4};
int * bla2 = bla;

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Maar waarom kun je niet gewoon unsigned char* = {} gebruiken net als char* = "TN"?

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 30-08 23:12
OlafvdSpek schreef op 25 september 2002 @ 16:13:
Maar waarom kun je niet gewoon unsigned char* = {} gebruiken net als char* = "TN"?
Omdat een unsigned char * geen array is. Je gebruikt een array init. notatie voor een pointer.

[edit]

Zoiets kan natuurlijk wel:

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
const char bla [] = { 'a','b','c' };

struct blabla
{
    blabla( const char * p_bla );

    const char * p_bla;
};

blabla::blabla( const char * p_bla )
{
    this->p_bla = p_bla;
}

void main()
{
    blabla c( bla );


    std::cout<<c.p_bla[0]<<std::endl;
    std::cout<<c.p_bla[1]<<std::endl;
    std::cout<<c.p_bla[2]<<std::endl;
    std::cin.get();
}      

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Maar is er dan geen manier om een pointer init constructie te gebruiken?

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 30-08 23:12
OlafvdSpek schreef op 25 september 2002 @ 16:28:
Maar is er dan geen manier om een pointer init constructie te gebruiken?
Zie boven ...

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Maar dan dus niet met een andere variabele, maar met de echte waardes.

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 30-08 23:12
OlafvdSpek schreef op 25 september 2002 @ 16:51:
Maar dan dus niet met een andere variabele, maar met de echte waardes.
Die andere variabele heeft toch waarden aan boord?

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • .oisyn
  • Registratie: September 2000
  • Nu online

.oisyn

Moderator Devschuur®

Demotivational Speaker

dit:
C++:
1
const char * bla = "abcd";


is hetzelfde als:

C++:
1
2
const char __constante_string[] = { 'a', 'b', 'c', 'd', 0 };
const char * bla = __constante_string;


behalve dan dat deze manier een extra naam introduceert. Dit is alleen een syntactisch iets; in je programma zal daar niets van terug te vinden zijn

Helaas kun je array inits niet gebruiken zoals je string literals kunt gebruiken. De waarde "abcd" kun je immers gewoon als parameter aan een functie meegeven. { 1, 2, 3, 4 } echter niet (jammer genoeg).

(daar is natuurlijk ook wel weer wat voor te zeggen: een string tussen quotes zal over het algemeen const char[] zijn (of wchar_t, maar iig 1 vast type), maar gewoon een setje waardes tussen accolades kan in principe alles zijn)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Ik wilde iets doen als (om een deel van een patch):
C++:
1
2
3
4
5
6
7
struct patch_t
{
  int offset;
  int size;
  unsigned char* s;
  unsigned char* d;
};

Maar dat kun je dus niet simpel initialiseren.

  • .oisyn
  • Registratie: September 2000
  • Nu online

.oisyn

Moderator Devschuur®

Demotivational Speaker

tja, je zou natuurlijk een utility functie kunnen maken:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
unsigned char * makeUCharArray (int num, ...)
{
    unsigned char * buf = new unsigned char [num];

    va_list l;
    va_start (l, num);
    for (int i = 0; i < num; i++)
        buf[i] = va_arg (l, unsigned char);

    return buf;
}

void jeFunctie ()
{
    patch_t patch =
    {
        12,
        253,
        makeUCharArray (3, 1, 2, 3),
        makeUCharArray (5, 1, 2, 3, 4, 5)
    };
    ...
}


(nog mooier zou zijn om een template functie te maken zodat je elk type array zo kunt maken, maar erg type-safe is het niet (die functie parameters kunnen namelijk alles zijn))

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

Lol, dit topic gemist; casten is toch moeilijk ;)

const unsigned char *p= (const unsigned char[]){ 65, 66, 67, 0 };

Werkt gewoon :)

  • .oisyn
  • Registratie: September 2000
  • Nu online

.oisyn

Moderator Devschuur®

Demotivational Speaker

mietje: uhm, bij mij toch echt niet hoor (MSVC 7)
gcc extension misschien?

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

.oisyn>> Problematisch :) Dit soort constructies mochten vroeger in C (voordat ISO/ANSI lastig ging doen) en zowat iedere compiler vreet dit dan ook in C-mode (met hooguit een warning). In C++ is het verboden en zul je die array een naampje moeten geven.

edit:
In C99 mag het wel weer :)

  • .oisyn
  • Registratie: September 2000
  • Nu online

.oisyn

Moderator Devschuur®

Demotivational Speaker

* wijst naar topictitel * ;)

MSVC 7 in C mode accepteert het overigens ook niet, en aangezien het niet de standaard is zou ik het ook niet gebruiken :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

/me wijst naar de extern "C" declaratie ;)

edit:
Het ligt er dus maar aan welke standaard, het mag niet volgens C89 maar wel volgens C99

  • .oisyn
  • Registratie: September 2000
  • Nu online

.oisyn

Moderator Devschuur®

Demotivational Speaker

dan mag jij verklaren waarom het volgende compilet:

C++:
1
2
3
4
5
6
7
extern "C"
{
    int * blaat ()
    {
        return new int[4];
    }
}


:Y)

(extern "C" is niet iets om je compiler om te schakelen naar C-mode ofzo, het geeft alleen maar aan wat voor linkage er gebruikt moet worden. Zie punt 7.5 van de Ansi C++ standaard)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Diadem
  • Registratie: Maart 2000
  • Laatst online: 31-05-2023

Diadem

fossiel

Wat is nu eigenlijk de meest gebruikelijke manier van schrijven?

int* blaat;
int *blaat;
int * blaat;

Ze zijn alledrie toegestaan natuurlijk, maar wat is standaard?

* Diadem vind de tweede manier het mooiste staan. Eerste is wel het meest logische echter.

Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life - Terry Pratchett


  • .oisyn
  • Registratie: September 2000
  • Nu online

.oisyn

Moderator Devschuur®

Demotivational Speaker

standaard :?

het is puur een persoonlijke voorkeur, nix standaards aan :)

ik doe meestal 1 spatie tussen het type en de ster(retjes), en dan indenteer ik de variabele nogmaals:

C++:
1
2
3
int          i;
Window *     window;
Blaat **     b;


alleen dat is wat lastig als je een pointer naar een functie declareert, want dat gaat niet op die manier :Y)

Als parameters voor functies gebruik ik gewoon dubbele spaties:
C++:
1
2
3
4
void func (int * a, int * b, const Vector & v)
{
    ...
}

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

My humble opinion: je declareert een variabele van het type 'pointer naar object x' en om die reden hoort het sterretje bij het type. Sowieso staat het netjes om zoals Oisyn doet de namen gelijk te indenteren, bijv.:
C++:
1
2
3
int          l_Integer;
Window*      l_Window;
Blaat**      l_Blaat;

Een echte bikkel gebruikt trouwens geen pointers in declaraties, daar heb je smart pointers voor en dan hoef je geen sterretjes meer te zien :)

Professionele website nodig?


Verwijderd

curry684 schreef op 26 september 2002 @ 20:47:
My humble opinion: je declareert een variabele van het type 'pointer naar object x' en om die reden hoort het sterretje bij het type.
De volgende declaratielijst demonstreert dat het sterretje bij de identifier hoort:
code:
1
int * a, b; // b is een int, geen int*

Bij het declareren van meerdere pointers zal het sterretje (en eventuele cv-qualifiers) dus voor iedere variabele herhaald moeten worden (erg stom imho).

  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Ik heb maar gekozen voor een int[], dan maar geen RLE. Het gaat toch om relatief weinig bytes die gepatched worden en zo is het automatisch vullen van de array ook iets makkelijker.

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Verwijderd schreef op 26 september 2002 @ 22:58:
[...]
De volgende declaratielijst demonstreert dat het sterretje bij de identifier hoort:
code:
1
int * a, b; // b is een int, geen int*

Bij het declareren van meerdere pointers zal het sterretje (en eventuele cv-qualifiers) dus voor iedere variabele herhaald moeten worden (erg stom imho).
En daarom houdt iedere nette programmeur zich aan de regel 'Een declaratie per coderegel', want voorkomen is beter dan debuggen :)

Professionele website nodig?


Verwijderd

curry684 schreef op 27 september 2002 @ 14:51:
[...]

En daarom houdt iedere nette programmeur zich aan de regel 'Een declaratie per coderegel', want voorkomen is beter dan debuggen :)
Voor programmeurs die niet begrijpen hoe declaratielijsten werken is die regel uiteraard van toepassing. Voor programmeurs die deze feature echter wèl begrijpen niet. Als je namelijk begrijpt hoe ze werken, leidt het gebruik ervan niet tot bugs.

  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Ook dan heb je meer kans op bugs hoor. Of in ieder geval moet je meer editen als je van een var het type wilt veranderen.
Pagina: 1