Skip to content

Instantly share code, notes, and snippets.

@lifeforce-dev
Last active April 24, 2020 06:37
Show Gist options
  • Save lifeforce-dev/3c29e88f55851b1ef5e3 to your computer and use it in GitHub Desktop.
Save lifeforce-dev/3c29e88f55851b1ef5e3 to your computer and use it in GitHub Desktop.
//------------------------------------------------------------------------------
//
// Just a simple cheat sheet(program?) to help beginning programmers
// understand the following concepts
// - Passing an address to a pointer
// - Passing by reference
// - Passing by value
// - Scoping
//
// Joshua Sanders
//
#include "Log.h"
#include <stdio.h>
#include <string.h>
#include <memory>
#include <string>
#include <functional>
namespace {
// Don't freak out! You don't need to worry about this section! Move along! Its okay!
class OutputHelper
{
public:
OutputHelper() {}
~OutputHelper() {}
void DataAddressOutput(int& a, int& b, char* functionName)
{
std::stringstream ss;
ss << "Speed address: " << &a << " HP address: " << &b << " | " << functionName << "\n";
LOG_DEBUG_CONSOLE(ss.str());
}
void DataValueOutput(int& a, int& b, char* functionName)
{
std::stringstream ss;
ss << "Speed value: " << a << " HP value: " << b << " | " << functionName << "\n";
LOG_DEBUG_CONSOLE(ss.str());
};
void DataPtrAddressOutput(int** ptrA, int** ptrB, char* functionName)
{
std::stringstream ss;
ss << "Speed* address: " << &(*ptrA) << " HP* address : " << &(*ptrB) << " | " << functionName << "\n";
LOG_DEBUG_CONSOLE(ss.str());
ss.str(std::string());
}
void DataPtrValueAddressOutput(int* ptrA, int* ptrB, char* functionName)
{
std::stringstream ss;
ss << "Speed* address: " << ptrA << " HP* address : " << ptrB << " | " << functionName << "\n";
LOG_DEBUG_CONSOLE(ss.str());
ss.str(std::string());
}
void PrintSpacerMessage()
{
LOG_DEBUG_CONSOLE(m_spacerMessage);
}
private:
const std::string m_spacerMessage = "\n--------------------------------------------------------\n\n";
};
}
// We pass an actual address by value here. This creates a local copy of two pointers
// speedAddress and hpAddress.
void PassAddressByValue(int* speedAddress, int* hpAddress)
{
OutputHelper helper;
*speedAddress = 75;
*hpAddress = 1000;
// This will print the address of the temporary local pointer itself.
helper.DataPtrAddressOutput(&speedAddress, &hpAddress, __FUNCTION__);
// This will print the address that the pointer stores.
helper.DataPtrValueAddressOutput(speedAddress, hpAddress, __FUNCTION__);
helper.DataValueOutput(*speedAddress, *hpAddress, __FUNCTION__);
} // The local speedAddress pointer and hpAddress pointer are destroyed here.
void PassByReference(int& speed, int& hp)
{
OutputHelper helper;
speed = 10;
hp = 20;
helper.DataAddressOutput(speed, hp, __FUNCTION__);
helper.DataValueOutput(speed, hp, __FUNCTION__);
}// Neither speed, or hp are destroyed here as their lifetime is managed outside of this scope.
// Creates a copy of speed and hp, and stores them into a different address on the stack.
void PassByValue(int speed, int hp)
{
OutputHelper helper;
speed = 10;
hp = 20;
helper.DataAddressOutput(speed, hp, __FUNCTION__);
helper.DataValueOutput(speed, hp, __FUNCTION__);
} // Leaving scope, the copy of speed and hp are destroyed here.
int main()
{
// Initialize.
OutputHelper helper;
int speed = 0;
int hp = 0;
helper.DataAddressOutput(speed, hp, __FUNCTION__);
helper.DataValueOutput(speed, hp, __FUNCTION__);
//--------------------------------------------------------------
helper.PrintSpacerMessage();
// What happens when we pass by value?
PassByValue(speed, hp);
helper.DataValueOutput(speed, hp, __FUNCTION__);
//--------------------------------------------------------------
helper.PrintSpacerMessage();
// What happens when we pass by reference?
PassByReference(speed, hp);
helper.DataValueOutput(speed, hp, __FUNCTION__);
///////////////////////////////////////////////////////////////////////////
// Bonus - This explains what was asked about passing an actual address in.
///////////////////////////////////////////////////////////////////////////
helper.PrintSpacerMessage();
speed = 7;
hp = 9;
// A pointer is a data type that stores an address. Therefore, the value of a pointer, IS an address.
// The address that a pointer points to does NOT have to be valid and as such is not guaranteed to be.
// This is actually passing the address of speed and hp.
PassAddressByValue(&speed, &hp);
helper.DataValueOutput(speed, hp, __FUNCTION__);
return 0;
}
//---------------------------------------------------------------
//
// Log.cpp
//
#include "Log.h"
#include <algorithm>
#define NOMINMAX
#include <windows.h>
namespace {
//==============================================================================
const int s_maxLength = 70;
enum MessageType
{
DEBUG_WINDOW,
CONSOLE
};
void AppendLoggingInfoToLog(const std::string& functionName, std::string& messageOut)
{
// Remove full path from the filename.
std::stringstream ss;
ss << messageOut;
ss << " | " << functionName << "\n";
messageOut = ss.str();
}
//==============================================================================
} // anonymous namespace
void Logger::LogDebugMessage(const std::string& message, LogSink messageType, const char* functionName)
{
if (message.empty())
return;
std::string guardedMessage = message;
//AppendLoggingInfoToLog(functionName, guardedMessage);
switch (messageType)
{
case DEBUG_WINDOW:
OutputDebugString(guardedMessage.c_str());
break;
case CONSOLE:
std::cout << guardedMessage;
break;
default:
break;
}
}
//---------------------------------------------------------------
//
// Log.h
//
#pragma once
#include <string>
#include <iostream>
#include <sstream>
namespace Logger {
//==============================================================================
enum LogSink
{
DEBUG_WINDOW,
CONSOLE
};
void LogDebugMessage(const std::string& message, LogSink messageType, const char* functionName);
#define LOG_DEBUG_CONSOLE(msg) \
{ \
LogDebugMessage(msg, Logger::CONSOLE, __FUNCTION__); \
}
#define LOG_DEBUG_OUTPUT_WINDOW(msg) \
{ \
LogDebugMessage(msg, Logger::DEBUG_WINDOW, __FILE__, __LINE__); \
}
//==============================================================================
} // namespace Logger
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment