1,075,985 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?

Posts by Narue Contributing to Articles being Marked Solved

Can anyone explain -in simple words as possible- what happens in the first code so that it prints the result that way?

Undefined behavior.

Narue
Bad Cop
Team Colleague
15,460 posts since Sep 2004
Reputation Points: 6,483
Solved Threads: 1,407
Skill Endorsements: 54

you can talk to him if u want for this.

Invite him to Daniweb and I'll be happy to tear him a new one.

Narue
Bad Cop
Team Colleague
15,460 posts since Sep 2004
Reputation Points: 6,483
Solved Threads: 1,407
Skill Endorsements: 54

graphics.h is certainly a problem, why do you use a graphics library from two decades ago?

Narue
Bad Cop
Team Colleague
15,460 posts since Sep 2004
Reputation Points: 6,483
Solved Threads: 1,407
Skill Endorsements: 54

I am getting a hex values as my output and i want to convert it into ascii so that it is readable.. does this help you?

No, it doesn't. Your terminology is confused, which makes it very difficult to understand exactly what you want without specific examples. Please post the exact output you want to see, since you're clearly not describing the problem adequately.

Narue
Bad Cop
Team Colleague
15,460 posts since Sep 2004
Reputation Points: 6,483
Solved Threads: 1,407
Skill Endorsements: 54

Shouldn't the strlen only return 2 (or 4 with 'ls'), shouln't the string in the system(); call be cut of, and shouln't I get a segmentation fault?

Yes, yes, and yes. Or no, no, and no. Or any combination thereof. Undefined behavior means any damn thing can happen, which includes working perfectly.

Narue
Bad Cop
Team Colleague
15,460 posts since Sep 2004
Reputation Points: 6,483
Solved Threads: 1,407
Skill Endorsements: 54

Only one problem, what is a masked text box?

Here's a hint for the future: always try to research things like this on your own first. The only if you come up with nothing or fail to understand what you've found should you ask for clarification. In this case, "masked text box" is standard terminology, and when passed to Google will certainly tell you what you want to know in the first hits.

Narue
Bad Cop
Team Colleague
15,460 posts since Sep 2004
Reputation Points: 6,483
Solved Threads: 1,407
Skill Endorsements: 54

But does that mean such a automatic aligning of the matrix in CONSOLE Application is impossible, No other robust method?

No, it just means I had neither the time nor the inclination to write a robust function for you when I think the whole concept is stupid. raw_gets() is a good starting point for adding the necessary checks and features to make it robust, but I'll leave that up to you.

Narue
Bad Cop
Team Colleague
15,460 posts since Sep 2004
Reputation Points: 6,483
Solved Threads: 1,407
Skill Endorsements: 54

tell me this... is the following code correct?

#include <iostream>
using namespace std;

int main () {
  int n;
  n=48:45:4c:4c:4f:20:57:4f:52:4c:44;
  cout << "ASC " << n << endl 
  return 0;
}

Is this a trick question? Of course it's not correct, as any compiler will tell you. How about explaining exactly what output you were expecting from this code, and I'll tell you how to achieve it correctly.

Narue
Bad Cop
Team Colleague
15,460 posts since Sep 2004
Reputation Points: 6,483
Solved Threads: 1,407
Skill Endorsements: 54

Wow! I never knew it was a C function. Thanks for sharing that, now onward i will not use that.

The fact that it's a function inherited from C is largely irrelevant. The important piece of information is that gets() is quite literally impossible to use safely. There's always a chance of buffer overflow, and you cannot avoid it. You can create the same problem using cin and C-style strings:

char buf[N];

cin >> buf; // No better than gets()

But at least here there's a fix for it:

char buf[N];

cin >> setw(N) >> buf; // All better

Of course, in C++ you should prefer to use the string class over C-style strings because they're easier to get right.

Narue
Bad Cop
Team Colleague
15,460 posts since Sep 2004
Reputation Points: 6,483
Solved Threads: 1,407
Skill Endorsements: 54

Please provide some new information to justify a second thread on the topic.

Narue
Bad Cop
Team Colleague
15,460 posts since Sep 2004
Reputation Points: 6,483
Solved Threads: 1,407
Skill Endorsements: 54

But why did you ask me to use at my risk?

Because it's example code and not robust enough to be usable in any kind of real program.

Narue
Bad Cop
Team Colleague
15,460 posts since Sep 2004
Reputation Points: 6,483
Solved Threads: 1,407
Skill Endorsements: 54

I understand your confusion, but please don't be tricked into thinking that the code isn't broken when you provide insufficient space for strcat().

Narue
Bad Cop
Team Colleague
15,460 posts since Sep 2004
Reputation Points: 6,483
Solved Threads: 1,407
Skill Endorsements: 54

as far as I can tell, strcat depends on the string pointed to by its first parameter to be large enough to hold the two strings.

Correct, it's your job to ensure that the destination has enough room.

but if I change the code to buff = malloc(sizeof(command)+2); (or pretty much any size at all, smaller than 42) the 'string' is expanded to be 42 characters long?

Expanded? No. C doesn't stop you from writing beyond the boundaries of an array. In Java, for example, you'll get an exception immediately, but C will happily write to memory you don't own and silently corrupt things. If you're lucky, you'll corrupt something that causes a fatal error, but in this case it seems as if you weren't lucky.

Narue
Bad Cop
Team Colleague
15,460 posts since Sep 2004
Reputation Points: 6,483
Solved Threads: 1,407
Skill Endorsements: 54

Obviously I have some wrong assumptions, because this prints "strsize = 8" no matter what.

Good call. buff is a pointer to char, so sizeof(buff) will always tell you what the size of a pointer to char is, not the length of the string it points to (if it points to a string at all, which isn't a safe assumption). What you want is the strlen() function, not sizeof.

Also note that strcat() expects the destination to be a valid string, which means you code is broken. This will fix it:

char* buff = malloc(sizeof(command)+42);

buff[0] = '\0'; /* Make buff a valid string */

strcat(buff, "notify-send \"notif finished\" \"Command: '");

Finally, it's good practice to check malloc() for failure. Otherwise you'll attempt to dereference a null pointer.

Narue
Bad Cop
Team Colleague
15,460 posts since Sep 2004
Reputation Points: 6,483
Solved Threads: 1,407
Skill Endorsements: 54

getcwd() returns the current working directory. That's the directory to which you can expect relative paths to resolve. Thus, it certainly explains why your relative path isn't finding the file if the current working directory is different. An easy solution would be using chdir() to force the current directory you want rather than using whatever happens to be the default.

Narue
Bad Cop
Team Colleague
15,460 posts since Sep 2004
Reputation Points: 6,483
Solved Threads: 1,407
Skill Endorsements: 54

Your compiler should support some form of getcwd(), check the documentation.

Narue
Bad Cop
Team Colleague
15,460 posts since Sep 2004
Reputation Points: 6,483
Solved Threads: 1,407
Skill Endorsements: 54

AES isn't especially difficult to implement from the specification. Ignoring the usual caveats of reinventing the wheel on important stuff like encryption, you could write your own class:

#ifndef JSW_AES_PROVIDER_H
#define JSW_AES_PROVIDER_H

#include <vector>

namespace jsw {
    namespace encryption {
        typedef std::vector<unsigned char> bytes_t;
        
        class aes_provider {
        public:
            aes_provider(bytes_t key) { reset(key); }

            void normalize(bytes_t& bytes);
            bytes_t encrypt(const bytes_t& bytes);
            bytes_t decrypt(const bytes_t& bytes);
        private:
            static bytes_t::value_type Sbox[][16];
            static bytes_t::value_type Sbox_inverse[][16];
            static bytes_t::value_type Rcon[][4];
        private:
            int Nb; // Input block length in 32-bit increments (always 4)
            int Nk; // Key length in 32-bit increments (4, 6, or 8)
            int Nr; // Number of rounds corresponding to key size (4:10, 6:12, 8:14)

            bytes_t key;                // Seed key
            std::vector<bytes_t> w;     // Key schedule
            std::vector<bytes_t> state; // State matrix

            void reset(bytes_t key);
            void key_expansion();
            void add_round_key(int round);
            void sub_bytes(bytes_t::value_type Sbox[][16]);
            void shift_rows();
            void inverse_shift_rows();
            void mix_columns();
            void inverse_mix_columns();
            bytes_t sub_word(bytes_t word);
            bytes_t rot_word(bytes_t word);
            unsigned char gfield_mul(unsigned char a, unsigned char b);
        };
    }
}

#endif
#include <stdexcept>
#include <vector>
#include "aes_provider.h"

namespace jsw {
    namespace encryption {
        void aes_provider::normalize(bytes_t& bytes)
        {
            // Add null padding to the input (modulo 128-bits for AES)
            while (bytes.size() % 16 != 0)
                bytes.push_back(0);
        }
        
        bytes_t aes_provider::encrypt(const bytes_t& bytes)
        {
            state = std::vector<bytes_t>(4, bytes_t(Nb));

            // Input to state
            for (int r = 0; r < 4; r++) {
                for (int c = 0; c < Nb; c++)
                    state[r][c] = bytes[r + 4 * c];
            }

            add_round_key(0);

            for (int round = 1; round < Nr; round++) {
                sub_bytes(Sbox);
                shift_rows();
                mix_columns();
                add_round_key(round);
            }

            sub_bytes(Sbox);
            shift_rows();
            add_round_key(Nr);

            bytes_t output(4 * Nb);

            // State to output
            for (int r = 0; r < 4; r++) {
                for (int c = 0; c < Nb; c++)
                    output[r + 4 * c] = state[r][c];
            }

            return output;
        }

        bytes_t aes_provider::decrypt(const bytes_t& bytes)
        {
            state = std::vector<bytes_t>(4, bytes_t(Nb));

            // Input to state
            for (int r = 0; r < 4; r++) {
                for (int c = 0; c < Nb; c++)
                    state[r][c] = bytes[r + 4 * c];
            }

            add_round_key(Nr);

            for (int round = Nr - 1; round > 0; round--) {
                inverse_shift_rows();
                sub_bytes(Sbox_inverse);
                add_round_key(round);
                inverse_mix_columns();
            }

            inverse_shift_rows();
            sub_bytes(Sbox_inverse);
            add_round_key(0);

            bytes_t output(4 * Nb);

            // State to output
            for (int r = 0; r < 4; r++) {
                for (int c = 0; c < Nb; c++)
                    output[r + 4 * c] = state[r][c];
            }

            return output;
        }

        bytes_t::value_type aes_provider::Sbox[][16] = {
            {0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76},
            {0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0},
            {0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15},
            {0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75},
            {0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84},
            {0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf},
            {0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8},
            {0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2},
            {0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73},
            {0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb},
            {0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79},
            {0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08},
            {0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a},
            {0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e},
            {0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf},
            {0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16} 
        };

        bytes_t::value_type aes_provider::Sbox_inverse[][16] = {
            {0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb},
            {0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb},
            {0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e},
            {0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25},
            {0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92},
            {0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84},
            {0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06},
            {0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b},
            {0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73},
            {0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e},
            {0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b},
            {0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4},
            {0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f},
            {0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef},
            {0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61},
            {0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d}
        };

        bytes_t::value_type aes_provider::Rcon[][4] = {
            {0x00, 0x00, 0x00, 0x00},  
            {0x01, 0x00, 0x00, 0x00},
            {0x02, 0x00, 0x00, 0x00},
            {0x04, 0x00, 0x00, 0x00},
            {0x08, 0x00, 0x00, 0x00},
            {0x10, 0x00, 0x00, 0x00},
            {0x20, 0x00, 0x00, 0x00},
            {0x40, 0x00, 0x00, 0x00},
            {0x80, 0x00, 0x00, 0x00},
            {0x1b, 0x00, 0x00, 0x00},
            {0x36, 0x00, 0x00, 0x00}
        };

        void aes_provider::reset(bytes_t key)
        {
            Nb = 4;

            switch (key.size()) {
            case 32:
                Nk = 8;
                Nr = 14;
                break;
            case 24:
                Nk = 6;
                Nr = 12;
                break;
            case 16:
                Nk = 4;
                Nr = 10;
                break;
            default:
                throw std::invalid_argument("Not a valid key size");
            }

            this->key = key;
            key_expansion();
        }

        void aes_provider::key_expansion()
        {
            bytes_t temp(4);

            w = std::vector<bytes_t>(Nb * (Nr + 1), bytes_t(4, 0));

            for (int i = 0; i < Nk; i++) {
                for (int byte = 0; byte < 4; byte++)
                    w[i][byte] = key[4 * i + byte];
            }

            for (int i = Nk; i < Nb * (Nr + 1); i++) {
                for (int byte = 0; byte < 4; byte++)
                    temp[byte] = w[i - 1][byte];

                if (i % Nk == 0) {
                    temp = sub_word(rot_word(temp));

                    for (int byte = 0; byte < 4; byte++)
                        temp[byte] ^= Rcon[i / Nk][byte];
                }
                else if (Nk > 6 && i % Nk == 4) {
                    temp = sub_word(temp);
                }

                for (int byte = 0; byte < 4; byte++)
                    w[i][byte] = w[i - Nk][byte] ^ temp[byte];
            }
        }

        void aes_provider::add_round_key(int round)
        {
            for (int r = 0; r < 4; r++) {
                for (int c = 0; c < Nb; c++)
                    state[r][c] ^= w[round * 4 + c][r];
            }
        }

        void aes_provider::sub_bytes(bytes_t::value_type Sbox[][16])
        {
            for (int r = 0; r < 4; r++) {
                for (int c = 0; c < Nb; c++)
                    state[r][c] = Sbox[state[r][c] >> 4][state[r][c] & 0x0f];
            }
        }

        void aes_provider::shift_rows()
        {
            std::vector<bytes_t> temp = state;

            for (int r = 1; r < 4; r++) {
                for (int c = 0; c < Nb; c++)
                    state[r][c] = temp[r][(c + r) % Nb];
            }
        }

        void aes_provider::inverse_shift_rows()
        {
            std::vector<bytes_t> temp = state;

            for (int r = 1; r < 4; r++) {
                for (int c = 0; c < Nb; c++)
                    state[r][(c + r) % Nb] = temp[r][c];
            }
        }

        void aes_provider::mix_columns()
        {
            std::vector<bytes_t> temp = state;

            for (int c = 0; c < 4; ++c) {
                state[0][c] = gfield_mul(temp[0][c], 2) ^ gfield_mul(temp[1][c], 3) ^ temp[2][c] ^ temp[3][c];
                state[1][c] = temp[0][c] ^ gfield_mul(temp[1][c], 2) ^ gfield_mul(temp[2][c], 3) ^ temp[3][c];
                state[2][c] = temp[0][c] ^ temp[1][c] ^ gfield_mul(temp[2][c], 2) ^ gfield_mul(temp[3][c], 3);
                state[3][c] = gfield_mul(temp[0][c], 3) ^ temp[1][c] ^ temp[2][c] ^ gfield_mul(temp[3][c], 2);
            }
        }

        void aes_provider::inverse_mix_columns()
        {
            std::vector<bytes_t> temp = state;

            for (int c = 0; c < 4; ++c) {
                state[0][c] = 
                    gfield_mul(temp[0][c], 0x0e) ^ gfield_mul(temp[1][c], 0x0b) ^ 
                    gfield_mul(temp[2][c], 0x0d) ^ gfield_mul(temp[3][c], 0x09);
                state[1][c] = 
                    gfield_mul(temp[0][c], 0x09) ^ gfield_mul(temp[1][c], 0x0e) ^ 
                    gfield_mul(temp[2][c], 0x0b) ^ gfield_mul(temp[3][c], 0x0d);
                state[2][c] = 
                    gfield_mul(temp[0][c], 0x0d) ^ gfield_mul(temp[1][c], 0x09) ^ 
                    gfield_mul(temp[2][c], 0x0e) ^ gfield_mul(temp[3][c], 0x0b);
                state[3][c] =
                    gfield_mul(temp[0][c], 0x0b) ^ gfield_mul(temp[1][c], 0x0d) ^ 
                    gfield_mul(temp[2][c], 0x09) ^ gfield_mul(temp[3][c], 0x0e);
            }
        }

        bytes_t aes_provider::sub_word(bytes_t word)
        {
            bytes_t result(4);

            result[0] = Sbox[word[0] >> 4][word[0] & 0x0f];
            result[1] = Sbox[word[1] >> 4][word[1] & 0x0f];
            result[2] = Sbox[word[2] >> 4][word[2] & 0x0f];
            result[3] = Sbox[word[3] >> 4][word[3] & 0x0f];

            return result;
        }

        bytes_t aes_provider::rot_word(bytes_t word)
        {
            bytes_t result(4);

            result[0] = word[1];
            result[1] = word[2];
            result[2] = word[3];
            result[3] = word[0];

            return result;
        }

        unsigned char aes_provider::gfield_mul(unsigned char a, unsigned char b)
        {
            unsigned char prod = 0;

            for (int i = 0; i < 8; i++) {
                if ((b & 1) == 1)
                    prod ^= a;

                bool is_set = (a & 0x80) == 0x80;

                a <<= 1;

                if (is_set)
                    a ^= 0x1b;

                b >>= 1;
            }

            return prod;
        }
    }
}
#include <algorithm>
#include <climits>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <string>
#include "aes_provider.h"

using namespace jsw::encryption;
using namespace std;

bytes_t random_key(int size)
{
    bytes_t key;

    generate_n(back_inserter(key), size, []{ 
        return rand() % UCHAR_MAX;
    });

    return key;
}

class dump_bytes {
    const bytes_t& _bytes;
public:
    dump_bytes(const bytes_t& bytes): _bytes(bytes) {}
    
    friend ostream& operator<<(ostream& out, const dump_bytes& self)
    {
        for_each(self._bytes.begin(), self._bytes.end(), [&](unsigned b) {
            out<< std::hex << std::setw(3) << b;
        });
    }
};

int main()
{
    string line;

    cout<<"Input: ";

    if (getline(cin, line)) {
        bytes_t bytes(line.begin(), line.end());
        aes_provider cipher(random_key(32));

        cipher.normalize(bytes);
        cout<<"Before:  "<< dump_bytes(bytes) << '\n';
        bytes = cipher.encrypt(bytes);
        cout<<"After:   "<< dump_bytes(bytes) << '\n';
        bytes = cipher.decrypt(bytes);
        cout<<"Restore: "<< dump_bytes(bytes) << '\n';
    }
}

;)

Narue
Bad Cop
Team Colleague
15,460 posts since Sep 2004
Reputation Points: 6,483
Solved Threads: 1,407
Skill Endorsements: 54

I know that with the pointer you use the "->" operator to access the object methods, and with the other one you use the "." operator, but what exactly is the difference between them?

In the first declaration, rectangle is a reference to an address where a Shape object happens to be stored. rectangle is not a Shape, it's a container for an address that will be interpreted as a Shape object. This differs from the second declaration where rectangle is a Shape object.

I suspect you're confused by the type of the pointer, Shape*, which says "the address I hold, if not null, will represent an object of type Shape". It's necessary for both pointer arithmetic and type checking, but doesn't change the simple fact that a pointer holds an address, not an object.

Narue
Bad Cop
Team Colleague
15,460 posts since Sep 2004
Reputation Points: 6,483
Solved Threads: 1,407
Skill Endorsements: 54

Wouldn't it be better if we just defined the functions before the main function instead of having a function prototype and a function definition in separate areas?

What if you want to break your program up into multiple files? What if you want to write a library that will be used in multiple programs?

Narue
Bad Cop
Team Colleague
15,460 posts since Sep 2004
Reputation Points: 6,483
Solved Threads: 1,407
Skill Endorsements: 54

I can't flag the post as bad as it is not a post it is a reputation comment.

You can always PM a moderator or admin with any concerns. We won't bite, I swear. ;) But as far as reputation goes, it's inherently subjective, so we'll typically not retract rep unless the comment breaks Daniweb's rules (eg. it's offensive or obscene). But it never hurts to ask.

Narue
Bad Cop
Team Colleague
15,460 posts since Sep 2004
Reputation Points: 6,483
Solved Threads: 1,407
Skill Endorsements: 54
 
© 2013 DaniWeb® LLC
Page rendered in 0.2703 seconds using 2.72MB