-
Notifications
You must be signed in to change notification settings - Fork 0
/
PrinciplesCPP.cpp
264 lines (221 loc) · 8.16 KB
/
PrinciplesCPP.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
// /* PrinciplesCPP.cpp : This file contains the 'main' function. */
// /* Program execution begins and ends there. */
// /* */
// Include some standard resources
#include <iostream>
#include <vector>
/* Pointers
Pointers are variables that hold memory address.
Iterators are a generic function used to traverse containers.
This function allows the programmer to implement read and write code
as the container is traversed.
*/
/* Overloading
Note that the new operation is overloadable.
source:
https://www.geeksforgeeks.org/overloading-new-delete-operator-c/
*/
#include<string>
class student
{
std::string name;
int age;
public:
student()
{
std::cout << "Constructor: \n" ;
}
student(std::string name, int age)
{
this -> name = name;
this -> age = age;
}
void display()
{
std::cout << "Name: " << name << std::endl;
std::cout << "Age: " << age << std::endl;
}
void * operator new(size_t size)
{
std::cout<< "Overloading new operator with size: " << size << std::endl;
void * p = ::operator new(size);
//void * p = malloc(size); will also work fine
return p;
}
void * operator new(size_t size, char c)
{
void *ptr;
ptr = malloc(size);
return ptr;
}
void operator delete(void * p)
{
std::cout<< "Overloading delete operator " << std::endl;
free(p);
}
};
/* Templates
source: https://www.cplusplus.com/doc/oldtutorial/templates/
"Function templates are special functions that can operate
with generic types. This allows us to create a function template
whose functionality can be adapted to more than one type or class
without repeating the entire code for each type."
*/
template <class T>
T GetMax (T a, T b) {
T result;
result = (a>b)? a : b;
return (result);
}
/* print vectors */
void printv(std::vector<int> const &input)
{
for (int i = 0; i < input.size(); i++) {
std::cout << input.at(i) << ' ';
}
}
// Unions
union
{
std::uint16_t a;
std::uint32_t b;
std::int8_t c;
} u1;
int main(int argc, char* argv[])
{
// Print Hello World! //
std::cout << "Hello World!\n"<<std::endl;
// Use the vector command from std namespace
std::cout << "\n USING VECTORS \n" << std::endl;
std::vector<int> v(22);
bool b = (v[6]);
printf("bool b = %d", !b); // returns 1
/* Note using namespace std;
source: https://www.geeksforgeeks.org/using-namespace-std-considered-bad-practice/
"The statement using namespace std is generally considered bad practice.
The alternative to this statement is to specify the namespace to which
the identifier belongs using the scope operator(::) each time we declare a type.
Although the statement saves us from typing std:: whenever we wish to access a class
or type defined in the std namespace, it imports the entirety of the std namespace
into the current namespace of the program. Let us take a few examples to understand
why this might not be such a good thing"
*/
// more vectors
std::cout << "\n \n" << std::endl;
std::cout << "\n MORE VECTORS \n" << std::endl;
std::vector<int> v1{ 1,2,3 };
std::vector<int> v2 = v1;
v1.push_back(4);
v2.push_back(5);
std::cout << "\n Vector 1 \n ";
printv(v1);
std::cout << "\n Vector 2 \n";
printv(v2);
std::cout << "\n \n" << std::endl;
/* Iterators
Use the ++ command to iterate an integer.
*/
std::cout << "\n USING ITERATORS \n" << std::endl;
int x = 10, y = 20;
std::cout << "x = " << x << " and y = " << y << std::endl;
std::cout << "x++ = " << x++ << " and ++y = "<< ++y << std::endl;
std::cout << "x-- = " << x-- << " and --y = "<< --y << std::endl;
// Templates
/* Using the template GetMax
*/
std::cout << "\n USING TEMPLATES \n" << std::endl;
int i=5, j=6, k;
long l=10, m=5, n;
k=GetMax<int>(i,j);
n=GetMax<long>(l,m);
std::cout << "k=GetMax<int>(i,j)=" << k << std::endl;
std::cout << "n=GetMax<long>(l,m)=" << n << std::endl;
std::cout << "\n \n" << std::endl;
// Structures
/* By default the access specifier
for members of struct is public,
whereas for members of class, it is private.
*/
std::cout << "\n USING STRUCTS \n" << std::endl;
typedef struct
{
unsigned int age ;
unsigned char gender ;
unsigned int size ;
} child_t;
// smallest size a variable of type child_t may occupy
printf("\n Size of struct: %li \n", sizeof(child_t));
// Returns size = 12 > 7
/* Permission to access data struct based on condition */
typedef struct
{
int sunday:1;
int monday:1;
//more days
int friday:1;
int saturday:1;
} weekdays;
std::cout << "\n \n" << std::endl;
/* const references
Declaring a parameter as a const reference
instead of declaring it as a regular
object allows the argument to be passed as a reference,
so if the passed object is large,
the program will require less memory
*/
std::cout << "\n USING OVERLOADING \n" << std::endl;
student * p = new student("Yash", 24);
p->display();
delete p;
std::cout << "\n \n" << std::endl;
// Size of a union
std::cout << "\n USING UNIONS \n" << std::endl;
std::cout <<"\n Size of u1: \n" << sizeof(u1);
std::cout << "\n \n" << std::endl;
/* lvalues and rvalues
source: https://docs.microsoft.com/en-us/cpp/cpp/lvalues-and-rvalues-visual-cpp
lvlaues are expressions that represent an object with an address.
The C++17 standard defines expression value categories as follows:
A glvalue is an expression whose evaluation determines
the identity of an object, bit-field, or function.
A prvalue is an expression whose evaluation initializes
an object or a bit-field, or computes the value
of the operand of an operator, as specified by the context
in which it appears.
An xvalue is a glvalue that denotes an object or bit-field
whose resources can be reused (usually because it is near
the end of its lifetime).
Example: Certain kinds of expressions involving rvalue references
(8.3.2) yield xvalues, such as a call to a function whose return type
is an rvalue reference or a cast to an rvalue reference type.
An lvalue is a glvalue that is not an xvalue.
An rvalue is a prvalue or an xvalue.
*/
/* Ternary Operator - Conditional (or Ternary) Operator (?:)
source: http://www.cplusplus.com/articles/1AUq5Di1/
The conditional operator is an operator used in C and C++
(as well as other languages, such as C#).
The ?: operator returns one of two values depending on the result
of an expression.
Syntax
(expression 1) ? expression 2 : expression 3
If expression 1 evaluates to true, then expression 2 is evaluated.
If expression 1 evaluates to false, then expression 3 is evaluated instead.
*/
std::cout << "TERNARY OPERATORS" << std::endl;
int OneOrTwo;
std::cout << "1 or 2?" << std::endl;
std::cin >> OneOrTwo;
std::string new_string;
if(OneOrTwo == 1)
{new_string = "selected 1.";}
else
{new_string = "not selected 1.";}
std::cout << "You have ";
std::cout << new_string << std::endl;
int ThreeOrFour;
std::cout << "3 or 4?" << std::endl;
std::cin >> ThreeOrFour;
std::string selected =(ThreeOrFour==3)?"selected 3.": "not selected 3.";
std::cout << "You have " << selected << std::endl;
}