#I need projects

50 messages · Page 1 of 1 (latest)

whole fable
#

So I started learning C++ 7 days ago and I've reached pointers and dynamic memory 2 days ago but I still don't get them and can't grasp the idea of pointers in my head. I need projects that would force me to understand the concept of pointers.

muted capeBOT
#

When your question is answered use !solved or the button below to mark the question as resolved.

Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question use !howto ask.

honest valve
#

Try implementing a linked list or dynamic array I guess

cursive finch
outer lintel
cursive finch
#

More like something to throw at "pointers are addresses" crowd

honest valve
#

Yeah wth is std::launder

dusk bolt
#

don't be confused with reference

whole fable
#

like for example
void func(int *pNum);
or
void func(int &num);

cursive finch
#

Can you tell more what are you confused about?

#

References and pointers are similar, just the notation is different and references can't be null

honest valve
#

I think they confused reference with the address-of operator

honest valve
whole fable
#

and the difference between it and passing an address

cursive finch
#

"Pointer" and "address" mean very similar things. People often use them interchangably

#

"Address" is to "pointer" is what "integer" is to int. We say that int stores integers, and pointers (like int *) store addresses

#

What confuses you about passing pointers?

dusk bolt
potent girder
#

Instead manual memory allocation you should be using RAII, and instead pointers you should be learning about life times, references and iterators. Learn the right way to do it in C++ first. In modern C++ manual memory allocation and pointers are only there to cover niche stuff. Only when you are proficient, only then, learn how to do it the C way for completion.

hollow urchin
cursive finch
#

And even then, I think it helps learning the basics of pointers before iterators

hollow urchin
#

std::optional<T&>
the lengths people will go to to avoid ordinary pointers...

terse egret
#

I didn't really get pointers til i started learning assembly and computer architecture

#

they're not very intuitive unless you understand how programs actually work

cursive finch
#

One problem I have with pointers is that when used as function parameters, they are ambiguous between "one object" and "array of objects". I've ran into this when doing automatic binding generation to other languages, since there you need different argument types for "optional reference to one element" and "optional reference to array"

#

If everyone was using optional<T &> for single objects and span<T> for arrays, and there were no pointers in function params or return types, that would make this easier for me

high escarp
#

I think you fell pray to the fact that they were introduced too early.
For pointers to matter in any program, it has to be large enough for you to need them.
Someone who started 7 days ago, you probably won't even be able to think of problems that pointers could solve.

Since you are learning about pointers then I presume that you understand the idea of a scope {}.
Variables created within the scope, that weren't dynamically allocated (ignore that one if you haven't learned yet about dynamic memory allocation) will get automatically destroyed when the program goes out of specific scope, ergo. finishes executing the code in the scope.
There is also a global scope which will get destroyed at the 'end' of the program.

Knowing that, if you have also learned about functions, how to create them etc. you will know that each function has it's own scope, therefore we can threat scope variables as existing in the context of a function or globally.
This means that if you call function in a function in a function... you get the idea, you might want a specific function to modify for you an object created in the scope of let's say main function.
Why? Because some parts of the code will always be repeating and creating function out of it will shorten the code. It's also more readable if you name the function properly rather than having someone interpret multiple lines or even more.
Well since the object was created in the main function then it's existance is known only to the function it was created in (in it's scope), so how can another function modify it?
Labels for memory (ergo. variables/objects) are only known in the context of the scope so trying to use the same label gets us nowhere.
You could create a global variable, for any beginner it seems like the easiest solution out there but any more advanced programmer will know it's a bad idea without a good justification and most of the time there is no any though depends on what you are writting the code for.

high escarp
#

Since the label will not exist in the context of function called in main, and we do not know it's address (it will get one once the system will start executing specific operation codes so we cannot know from the standpoint of the code), what can we do?
Well if you know how to create a function then you probably also know that functions can have parameters.
You also know what references are (aliases for existing labels and therefore names refering to an address), and so you can add a parameter to a function that will require user to pass an variable/object of specific type to it on invocation.
With that you can refer to that specific variable/object/memory with a new label whether the same or different name and so you can modify it's value.
Pointers can do the same, and more because they allow you to dereference the memory address and access it's value indirectly (they hold the value of an memory adress).

One power that pointers give is that they can change what they point to where references will always point to what they were initialized with.
That also means that the object you will point to will have to be created beforehand.
Pointers on the other hand can be initialized to nullptr or NULL (C++ should use nullptr, but you can encounter NULL from C) and therefore introduces responsibility with that power because nullptr conveys to any programmer that the pointer is not yet pointing to any variable/object/valid memory or it never did in the first place (this is unfortunately almost never known with pointer alone so it's often ambiguous information, still it does help us).
The other is that if there is a known accessible address of the memory that isn't necessarily part of the memory of the program, you can use pointer to grab value from that memory (for that you need to know the type & size of the memory since any memory can be interpreted willy-nilly how you want.

#

Some programs may need more memory but they don't know beforehand how much because it may depend on the user needs (reading files of varying sizes without limitting it to some array of fixed max length).

#

There is also a way to create a pointer to a function with specific signature.
That means that such pointer can change address of a function it is pointing to, to adress of another function.
How is that useful? Well say that you have a program for designers that allows for creating a button, and giving that button a function (scripted or existing, known to a program).
Pointers can wait before they are initialized with a valid address so we can tell which button should try to invoke a function on let's say click event and which should not.
Pointer can also change it's value and therefore a button that had been assigned a function by user can have it reassigned.
Depending on how you use it, it can create very interesting features in the program.

#

One other use is polymorphism (a topic for later, sicne you just started don't bother with it yet).
In the future you will learn that data structures/classes can inherit qualities of other data structures/classes and the limitations of this feature.
You can have many different ds/classes that will inherit from some specific class and therefore each othese different ds/classes have a commonality.
A pointer to the ds/class type that these ds/classes inherited from can also point to an object of a ds/class that inherited from it.
There's far more here to talk about here and many pitfalls too, but the gist of it is that it allows us to have one type of a pointer to operate on all these objects of different types from a common standpoint.

#

Another thing that pointers allow for is arithmetics, since pointers hold memory address which is a number then adding/substracting etc. will cause it to point to the memory address after the operation.
This is useful in many ways but one basic feature is being able to point to any element of an array without having to use a name of that array again after assigning the memory address of an array the first time.
Pointers also allow for indexing, since indexing is really an memory address arithmetic the creators of C++ allowed use of indexing operator on pointers by default, no need to even define it in any way.

high escarp
#

As for projects:
Create bunch of const char* that will hold a string like:

const char* my_text  = "Hello World! A common string"
const char* my_text2 = "Second string with different content and size"
const char* my_text3 = "Yet another string!"

If you feel fine with this then it's proably better to create bunch of arrays of such strings.

const char* string_array[] = {
   "Hello World! A common string",
   "Second string with different content and size",
   "Yet another string!" //, more if needed be
};

// here another array
// and another array, whatever you get the gist

With that you can use a single pointer to judge length of any string in any array by using pointer arithmetic to check letter by letter until the value (derived through dereferencing) is equal to \0 which in case of constants like above is a given at the end of a string defined with "".
You can do so by creating a pointer to a const char (remember const char* isn't a constant pointer but a pointer to constant char and so you can change the pointer but you cannot use the pointer to change the value of the specific const char in memory of the array. A constant pointer to constant char would be defined as const char* const which we don't need here.
With loops you can keep adding to the pointer in order to move it to another character, one by one until you encounter character \0, where you should stop and let's say display the length of the string.
Make sure that you know the size of each string beforehand as to verify correctness.

#

Later if you know how to create functions, try to create a function that will return a size of such string, where the string would be passed on parameter or if you want to create a function that takes a pointer to an array and it's size.

#

What I did here is mostly what you would do if you used primitives but if you know std::array you can use it instead, there is no problem here so as long as you use pointers properly.

std::array<const char*> string_array = {
// strings here...
};

You can later do string_array[0] to get the address of the first string array or string_array.data().

#

Not sure which school have you started with, some teach by using primitives some by using standard library classes, either way eventually you will know both.

#

You can also create alternative program which would create an array of pointers to such string array and you would use the fact that pointers can change what they point to in order to create a temporary reordering without changing the main array of strings in any way.

#

Someone here suggested a linked list, this program would in some sense emulate what linked lists are used for, it's just simpler in a way, messier but does not require you to know how to create data structures.

#

You can also create string array of words (think Dark Souls messaging system).
Then allow the user to keep asking which word to put and where.

#

You can try simulating database behaviour by creating an array for each column.
Think of functionalities that you can create to let the user display some interesting records from such data base.
In the below I don't mean that you have to create an array of pointers to functions (but you can), instead it's enough that user will give you a number 0~N (where N is some maximum) and then based on some if..else execute what you have to in order to provide what user requested.
For examble a function of index 0 could display record at index.
Function of index 1 could display record which holds specific value at specific column.
Function of index 2 could display users who hold numeric values from range of A~B.
Whatever you can think of, challenge yourself if you deem the task too easy.

A view of a table in the database is in some sense a table that holds only copies of records that were interesting for specific problem.
You can create a table that holds such records or even points to them.
If you use pointers then the values in the view will always be up to date, no need to copy but the access to values in columns will be indirect and therefore slower (price of using pointers).
Then again it would be training so who cares!

#

If you are feeling up to the task you can create a program where you want to connect to things with each other.
For example a word in another language and the translation.
Make sure they are mixed up and make sure the user can change what points to what (you can use numbers to let the user to specify in an easy way what should point to what and later once the user gave input just translate the 'index' that user specified to that specific memory adress that the value is held in).

#

You can simulate a macro program that is supposed to invoke specific functions in the program in an order specified by the user.
Create an array of pointers to specific function signature, for simplicity every single function will have the same signature but do different things and have different names. That means the same parameter types on the same positions and the same amount of parameters.
This array should have assigned all of the functions that the user is allowed to use.

On specific input allow user to display list of available functions with their indexes.
Create another function, of bigger size and a variable that will hold the actual count of how many functions the user placed in this array, also another variable to hold the maximum in case user tries to go beyond it.

Some kind of input should allow the user to cease adding functions to the macro.
Once the user specified he finished, you should invoke all the functions one by one unless the count of added to the macro functions is 0.

hollow urchin
#

a really simple program with pointers is anything that needs to hold an unlimited amount of data, like if you ask to type in a bunch of strings, then print them in the opposite order