Skip to content

Commit

Permalink
More changes to array
Browse files Browse the repository at this point in the history
  • Loading branch information
joergboe committed Feb 15, 2021
1 parent 46a30ce commit d806dda
Show file tree
Hide file tree
Showing 3 changed files with 154 additions and 21 deletions.
18 changes: 14 additions & 4 deletions Arrays/.cproject
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.debug.1577247805" name="Debug" optionalBuildProperties="org.eclipse.cdt.docker.launcher.containerbuild.property.volumes=,org.eclipse.cdt.docker.launcher.containerbuild.property.selectedvolumes=" parent="cdt.managedbuild.config.gnu.exe.debug">
<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.debug.1577247805" name="Debug" optionalBuildProperties="org.eclipse.cdt.docker.launcher.containerbuild.property.selectedvolumes=,org.eclipse.cdt.docker.launcher.containerbuild.property.volumes=" parent="cdt.managedbuild.config.gnu.exe.debug">
<folderInfo id="cdt.managedbuild.config.gnu.exe.debug.1577247805." name="/" resourcePath="">
<toolChain id="cdt.managedbuild.toolchain.gnu.exe.debug.1024125166" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.debug">
<targetPlatform id="cdt.managedbuild.target.gnu.platform.exe.debug.1827130579" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.debug"/>
Expand All @@ -23,7 +23,9 @@
<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug.1214686500" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug">
<option id="gnu.cpp.compiler.exe.debug.option.optimization.level.102110396" name="Optimization Level" superClass="gnu.cpp.compiler.exe.debug.option.optimization.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.optimization.level.none" valueType="enumerated"/>
<option defaultValue="gnu.cpp.compiler.debugging.level.max" id="gnu.cpp.compiler.exe.debug.option.debugging.level.2088551580" name="Debug Level" superClass="gnu.cpp.compiler.exe.debug.option.debugging.level" useByScannerDiscovery="false" valueType="enumerated"/>
<option id="gnu.cpp.compiler.option.dialect.std.501708925" superClass="gnu.cpp.compiler.option.dialect.std" useByScannerDiscovery="true" value="gnu.cpp.compiler.dialect.c++11" valueType="enumerated"/>
<option id="gnu.cpp.compiler.option.dialect.std.501708925" name="Language standard" superClass="gnu.cpp.compiler.option.dialect.std" useByScannerDiscovery="true" value="gnu.cpp.compiler.dialect.c++11" valueType="enumerated"/>
<option id="gnu.cpp.compiler.option.warnings.allwarn.1926678455" name="All warnings (-Wall)" superClass="gnu.cpp.compiler.option.warnings.allwarn" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<option id="gnu.cpp.compiler.option.warnings.toerrors.1394392427" superClass="gnu.cpp.compiler.option.warnings.toerrors" useByScannerDiscovery="false" value="false" valueType="boolean"/>
<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.131249513" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
</tool>
<tool id="cdt.managedbuild.tool.gnu.c.compiler.exe.debug.1169359817" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.exe.debug">
Expand Down Expand Up @@ -118,5 +120,13 @@
</scannerConfigBuildInfo>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
<storageModule moduleId="refreshScope"/>
</cproject>
<storageModule moduleId="refreshScope" versionNumber="2">
<configuration configurationName="Debug">
<resource resourceType="PROJECT" workspacePath="/Arrays"/>
</configuration>
<configuration configurationName="Release">
<resource resourceType="PROJECT" workspacePath="/Arrays"/>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
</cproject>
148 changes: 137 additions & 11 deletions Arrays/src/Arrays.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,70 @@
using namespace std;

// function definitions to demonstrate different kind of array parameters

void wrongUseOneArray(int inp[3]);

// array as parameter
void useOneArray(int inp[], size_t size);

// array reference as parameter
void useOneArray(int (&inp)[3]);

// std::array (c++11) has the semantics and effectivity of an integrated
using MyArray = array<char, 5>;
// std::array as parameter
void useOneArray(MyArray & inp);

int main() {
cout << "*** Integrates arrays; subscriptions and sizes ***" << endl;
cout << "*** Integrates arrays; subscriptions and sizes ***\n\n"
"A declaration 'T name[size]' defines a array of type T\n"
"The size of the array is deducted from from the initializer";
int a1[] = {0, 1, 3};
cout << "use subscriptions to get array elements : " << a1[0] << ", " << a1[1] << ", " << a1[2] << endl;
int a2[3];
cout << "To define type aliases use 'typedef' or 'using'\n";
typedef int ArrayType1[3];
cout << "The size may be undefined\n";
typedef int ArrayType2[];
cout << "In using declarations use 'T[size]'\n";
using ArrayType3 = int[3];
using ArrayType4 = int[];
typedef char const * ArrayType5[];
using ArrayType6 = char const * [];
cout << "typeid(ArrayType1).name(): " << typeid(ArrayType1).name() <<
"\ntypeid(ArrayType2).name(): " << typeid(ArrayType2).name() <<
"\ntypeid(ArrayType3).name(): " << typeid(ArrayType3).name() <<
"\ntypeid(ArrayType4).name(): " << typeid(ArrayType4).name() <<
"\ntypeid(ArrayType5).name(): " << typeid(ArrayType5).name() <<
"\ntypeid(ArrayType6).name(): " << typeid(ArrayType6).name() << endl;

cout << "\nTo declare an array, the size must be known at compile time:\n";
//ArrayType4 at4; // error: storage size of ‘at4’ isn’t known

cout << "\nInitialization with initializer can have 2 forms: old style or extended initializer list (since C++11)\n";
short int shortIntArray1[] = {1, 127};
short int shortIntArray2[] {1, 127};
cout << "\nEmpty initializer list with size deduction yields a array of size 0\n";
char charArr1[] = {};
char charArr2[] {};
cout << "size charArr1: " << sizeof charArr1 << endl;
cout << "size charArr2: " << sizeof charArr2 << endl;
cout << "Empty initializer list yields a zero initialized array:\n";
int intArr1[4]{};
cout << "intArr1: ";
for (auto x : intArr1)
cout << x << " ";
cout << endl;
cout << "\nThe {} initializer prevents narrowing conversions:\n";
//short int shortIntArray3[] = {1234567, 127}; // error: narrowing conversion of ‘1234567’ from ‘int’ to ‘short int’ inside { } [-Wnarrowing]

cout << "\nUse subscriptions to get array elements : " << a1[0] << ", " << a1[1] << ", " << a1[2] << endl;
cout << "sizeof a1 = " << sizeof a1 << " : delivers the size of the array in memory" << endl;

size_t elem = sizeof a1 / sizeof(int);
cout << "a1 has " << elem << " elements\n";

cout << "\n*** Assignments and for loop ***" << endl;
int a2[3];
//a2 = a1; //error: invalid array assignment
cout << "a2 = a1; !!! no array assignment possible: use for loop instead\n";
for (size_t i=0; i<elem; ++i)
a2[i] = a1[i];
Expand All @@ -46,29 +90,57 @@ int main() {
cout << "sizeof *ap = " << sizeof *ap << " : delivers the size of the element type sizeof(int) = " << sizeof(int) << endl;
cout << "Pointer arithmetic gives access to array elements: " << *ap << ", " << *(ap+1) << ", " << *(ap+2) << endl;

cout << "\n*** Array in heap memory may be created and with initializer list ***";
int * a3 = new int[4]{ 5, 6, 7, 8};
cout << "sizeof a3 = " << sizeof a3 << " : delivers the size of the pointer type = " << sizeof(void*) << endl;
cout << "\n*** Arrays in heap memory may be created and with initializer list ***\n"
"But here the array size is not deducted!\n";
auto a3 = new int[4]{5, 6, 7, 8};
cout << "size of a3 = " << sizeof a3 << " : delivers the size of the pointer type = " << sizeof(void*) << endl;
cout << "sizeof *a3 = " << sizeof *a3 << " : delivers the size of the element type sizeof(int) = " << sizeof(int) << endl;
cout << "No idea how many elements in *a3. It is just a pointer." << endl;
cout << "No idea how many elements in *a3. It is just a pointer to int: " << typeid(a3).name() << endl;

cout << "To delete heap arrays use delete[]" << endl;
delete[] a3;
cout << "\nThe empty initializer list yields a zero initialized array.\n"
"A heap or stack allocated array with no initializer has undefined values (are probably 0):\n";
{
auto a4 = new int[4]{};
auto const a5 = new int[4];
auto ax = a3; // do not alter the original pointer; we need it for the deletion
cout << "a3 = ";
for (int i = 0; i < 4; ++i)
cout << *ax++ << " ";
cout << "\na4 = ";
ax = a4;
for (int i = 0; i < 4; ++i) {
cout << *ax << " ";
++ax;
}
cout << "\na5 = ";
for (int i = 0; i < 4; ++i)
cout << a5[i] << " ";

cout << "\n*** string literals *** are char arrays " << typeid("abc").name() << endl;
cout << "\nTo delete heap arrays use delete[]" << endl;
delete[] a3;
delete[] a4;
delete[] a5;
}
cout << "\n*** string literals *** are constant char arrays " << typeid("abc").name() << endl;
cout << "a terminating null char is automatically appended : sizeof \"abc\" = " << sizeof "abc" << endl;
//"abc"[2] = 'x'; // error: assignment of read-only location ‘"abc"[2]’
char str[] = "abcd";
char mychar = str[1];
cout << "\"abcd\"[1]=" << "abcd"[1] << "=" << mychar << endl;
const char * charptr = "xyz";
cout << "and are converted to const char * charptr=" << charptr << endl;
cout << "and are silently converted to const char * charptr=" << charptr << endl;

cout << "\n*** This is an amazing hack!\n"
"a[j] == *(&a[0]+j) == *(a+j) == *(j+a) == j[a]" << endl;
//a[j] == *(&a[0]+j) == *(a+j) == *(j+a) == j[a]
cout << "\"abcd\"[1]=" << "abcd"[1] << endl;
cout << "1[\"abcd\"]=" << 1["abcd"] << endl;

cout << "*** array parameters ***\n"
"The first obvious attempt is wrong: The information about the array size is lost.\n"
"(because of the array to pointer decay)\n";
int aw1[] = { 10, 20, 30, 40, 50 };
wrongUseOneArray(aw1);
useOneArray(a1, 3);
useOneArray(a1);
array<char, 5> chararr{"abcd"};
Expand All @@ -79,10 +151,64 @@ int main() {
int ia[][2] = {{1,2}, {3,4}, {5,6}};
cout << "typeid: " << typeid(ia).name() << " size: " << sizeof ia << endl;

cout << "\n*** More array declarations ***\n"
"\nArray of pointer type\n";
char const * charPointerArray[] = { "string1", "string2"};
cout << "Sizeof charPointerArray: " << sizeof charPointerArray << endl;

cout << "\nArray reference (must use parentheses to force correct declarator binding):\n";
char const * (& charPointerArrayRef)[2] = charPointerArray; //
cout << "Print *charPointerArrayRef: ";
for (std::size_t i = 0; i < (sizeof charPointerArrayRef / sizeof(char const *)); ++i)
cout << charPointerArrayRef[i] << " "; // it is not ! (*charPointerArray)[i]
cout << endl;
cout << "Alias definitions of array references:\n";
typedef char const * (& CharPointerArrayRefType1)[2];
using CharPointerArrayRefType2 = char const * (&)[2];
cout << "Type of CharPointerArrayRefType1: " << typeid(CharPointerArrayRefType1).name() << endl <<
"Type of CharPointerArrayRefType2: " << typeid(CharPointerArrayRefType2).name() << endl;

cout << "Cast an array pointer into a reference with 'reinterpret_cast<>()':\n";
char const * * heapArray1 = new char const *[2] {"'a new string'", "'one more new string'"};
CharPointerArrayRefType1 heapArray1Ref = reinterpret_cast<char const * (&)[2]>(*heapArray1);
cout << "Print heapArray1: ";
for (std::size_t i = 0; i < 2; ++i)
cout << heapArray1[i] << " ";
cout << endl;
cout << "Print heapArray1Ref: ";
for (auto x : heapArray1Ref)
cout << x << " ";
cout << endl;

cout << "\nPointer to array type (must use parentheses to force correct declarator binding):\n";
char const * (* charPointerArrayPointer)[2] = &charPointerArray;
cout << "Sizeof charPointerArrayPointer: " << sizeof charPointerArrayPointer << endl;
cout << "Print *charPointerArrayPointer: ";
for (int i = 0; i < 2 ; ++i)
cout << (*charPointerArrayPointer)[i] << " ";
cout << endl;
using charPointerArrayPointer2 = char const * (*) [2];
cout << "charPointerArrayPointer2: " << typeid(charPointerArrayPointer2).name() << endl;

cout << "\n\n*** Conclusion ***\n"
"Integrated arrays are silently converted to pointers at the slightest occasion.\n"
"Thus the size information is lost. std::array provides a type save alternative.\n"
"Integrated arrays have always a fixed size which must be known at compile time.\n"
"If variable size array is required use std::vector.\n";

cout << "END" << endl;
return 0;
}

void wrongUseOneArray(int inp[3]) {
cout << "\n*** void wrongUseOneArray(int inp[3]) ***\n";
cout << "typeid(inp): " << typeid(inp).name() <<
"'inp' is decayed to a pointer and the actual array size is not available!\n"
"inp = ";
for (int i = 0; i < 3; ++i) cout << inp[i] << " ";
cout << "\nNote: the pointer can be used with subscription like an array.\n";
}

void useOneArray(int inp[], size_t size) {
cout << "\n*** void useOneArray(int inp[], size_t size) ***\n";
cout << "The usual way to hand over an array int inp[] but the information about the size of the array is lost\n";
Expand Down
9 changes: 3 additions & 6 deletions PointerToMember/src/PointerToMember.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
// Author : joergboe
//============================================================================

#include <cstdlib>
#include <iostream>

using namespace std;

class Base {
Expand All @@ -20,11 +22,6 @@ class Base {
printVars();
cout << " val=" << val << endl;
}
/*void print2(int val) const {
cout << "print2";
printVars();
cout << " val=" << val << endl;
}*/
void setA(char c_) {
a = c_;
}
Expand Down Expand Up @@ -170,5 +167,5 @@ int main() {

cout << "END" << endl;

return 0;
return EXIT_SUCCESS;
}

0 comments on commit d806dda

Please sign in to comment.