So, I am currently making a little code with some pointers. I am trying to get every values of an array, and their respective address. However, the initial array is empty, and the user has to enter numbers as an input, which ends up being added to the array itself. Then, I want to get the address of each value that the user added, one by one. Everything works fine, except one thing; I want every value to have a static address. However, I noticed that at every inputs, every values had a different address than the one they had before. I tried to put the array as a global static variable, but it still doesn't work. Any help?
Thanks for everyone who takes their time to answer! <3
Full code:
using System;
public class ClearIt
{
public int k = 8;
}
public static class Arr
{
public static int StaticAddress;
public static int[] x = { };
}
public class Class
{
public static unsafe void Main()
{
ClearIt clearIt = new ClearIt();
int k2 = clearIt.k;
for (int j = 0; j < 1;)
{
string Read = Console.ReadLine();
int ReadToInt;
bool isTrue;
isTrue = int.TryParse(Read, out ReadToInt);
if (!isTrue)
{
return;
}
int StaticAdd = Arr.StaticAddress = ReadToInt;
if (k2 > 0)
{
var xList = Arr.x.ToList();
xList.Add(StaticAdd);
Arr.x = xList.ToArray();
Array.Sort(Arr.x);
k2--;
}
else if(k2 == 0)
{
Console.ForegroundColor = ConsoleColor.Red;
var xList2 = Arr.x.ToList();
xList2.Clear();
Arr.x = xList2.ToArray();
Console.WriteLine("Array cleared.");
Console.ForegroundColor = ConsoleColor.White;
k2 = 8;
}
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("\nValues\tAddresses");
for (int i = 0; i < Arr.x.Length; i++)
{
fixed (int* y = &Arr.x[i])
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("\n" + *y + $"\t{(long)y:X}\n");
Console.ForegroundColor = ConsoleColor.White;
}
}
}
}
}
The short answer is that everytime you assign to Arr.x you are creating a new array and a new part of memory is used.
The statement below for example causes Arr.x address to change
Arr.x = xList2.ToArray();
If you do not want to change the address of Arr.x, then only assign it once to the maximum length, and keep track of the item count actually stored.
My best guess is that you are trying to do something like this
where the addresses in memory do not change when items are added or the
array is cleared. After the 8th number is added, the list clears
and more numbers can be added
As you can see the address value does not change.
I am using fixed buffer arrays to store the values, instead of the regular array. Here is the code that generates the output above
class Program
{
static void Main(string[] args)
{
var arr = new FixedArray();
do
{
Console.Clear();
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine($"{"offset"}\t{"address"}\t{"value"}");
for (int i = 0; i < arr.Count; i++)
{
Console.ForegroundColor = ConsoleColor.Gray;
Console.Write($"{i}");
Console.ForegroundColor = ConsoleColor.Yellow;
Console.Write($"\t{arr.GetItemAddress(i)}");
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine($"\t{arr[i]:X}");
Console.ForegroundColor = ConsoleColor.Gray;
}
if (arr.Count == 0)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Array Cleared.");
Console.ForegroundColor = ConsoleColor.Gray;
Console.WriteLine();
}
Console.WriteLine("Enter Value:");
string input = Console.ReadLine();
if (int.TryParse(input, out int value))
{
if (arr.Add(value))
{
}
else
{
arr.Clear();
}
}
else
{
return;
}
} while (true);
}
}
and FixedArray is the object that actually stores the data
public unsafe struct FixedArray
{
public const int Size = 8;
fixed int data[Size];
public FixedArray(params int[] array) : this()
{
Count = Math.Min(Size, array.Length);
fixed (int* ptr = data)
{
for (int i = 0; i < Count; i++)
{
ptr[i] = array[i];
}
}
}
public IntPtr GetItemAddress(int offset = 0)
{
fixed (int* ptr = &data[offset])
{
return (IntPtr)ptr;
}
}
public int this[int offset]
{
get
{
if (offset >= 0 && offset < Count)
{
return data[offset];
}
return 0;
}
}
public int Count { get; private set; }
public void Clear() { Count = 0; }
public bool Add(int x)
{
if (Count < Size)
{
data[Count] = x;
Count++;
return true;
}
return false;
}
public int[] ToArray()
{
int[] array = new int[Count];
fixed (int* ptr = data)
{
for (int i = 0; i < Count; i++)
{
array[i] = ptr[i];
}
}
return array;
}
}
You don't have to use a fixed buffer array. You can just use a standard array, but with the readonly keyword so it only gets assigned once. Use the class below as a replacement to FixedArray above.
public class StdArray
{
public const int Size = 8;
public int Count { get; private set; }
readonly int[] data;
public StdArray(params int[] array)
{
data = new int[Size];
Count = Math.Min(Size, array.Length);
Array.Copy(array, data, Count);
}
public unsafe IntPtr GetItemAddress(int offset = 0)
{
fixed (int* ptr = &data[offset])
{
return (IntPtr)ptr;
}
}
public int this[int offset]
{
get
{
if (offset >= 0 && offset < Count)
{
return data[offset];
}
return 0;
}
}
public void Clear() { Count = 0; }
public bool Add(int x)
{
if (Count < Size)
{
data[Count] = x;
Count++;
return true;
}
return false;
}
public int[] ToArray()
{
int[] array = new int[Count];
Array.Copy(data, array, Count);
return array;
}
}
Related
This is the static array I have been given in making a RPN calculator. From this code the RPN calculator adds and subtracts. Now I need to extend my code to multiply and divide but I cant I don't know how.
public class IntStack
{
private const int maxsize = 10;
private int top = 0;
private int[] array = new int[maxsize];
public void Push(int value)
{
array[top++] = value;
}
public int Pop()
{
return array[--top];
}
public int Peek()
{
return array[top - 1];
}
public bool IsEmpty()
{
return top == 0;
}
public bool IsFull()
{
return top == maxsize;
}
public string Print()
{
StringBuilder output = new StringBuilder();
for (int i = top - 1; i >= 0; i--)
output.Append(array[i] + Environment.NewLine);
return output.ToString();
}
}
Here are some methods you can add to your IntStack class that will perform the multiply and division operations. I've added minimal error checking.
public void Multiply()
{
if (array.Length < 2)
return;
var factor1 = Pop();
var factor2 = Pop();
Push(factor1 * factor2);
}
public void Divide()
{
if (array.Length < 2)
return;
var numerator = Pop();
var divisor = Pop();
if (divisor == 0) { // Return stack back to original state.
Push(divisor);
Push(numerator);
return;
}
Push(numerator / divisor);
}
This is homework, but a small portion...
I'm trying to return the largest number in an array using arr.MAX(); , but I keep on getting zero.
After debugging, I can see that values are being stored (from the user) yet it still returns zero.
The method in question is at the bottom.
Class ElectionUI
{
public void candidateInfo()
{
do
{
for (int i = 0; i < theElection.CandidateNames.Length; i++)
{
Console.Write("Please enter the name for Candidate #" + (i +
1) + ": ");
theElection.CandidateNames[i] = Console.ReadLine();
Console.Write("Please enter the number of votes for: {0}: ",
theElection.CandidateNames[i]);
theElection.NumVotes[i] = int.Parse(Console.ReadLine());
Console.WriteLine("");
}
} while (theElection.NumVotes.Length < 5);
}
}
Class Election
{
private string[] candidateNames = new string[5];
private int[] numVotes = new int[5];
//get/set Candidate Names
public string[] CandidateNames
{
get { return candidateNames; }
set { candidateNames = value; }
}
//Get/Set Candidate votes
public int[] NumVotes
{
get { return numVotes; }
set { numVotes = value; }
}
public void findWinner()
{
int max = NumVotes.Max();
for (var i = 0; i < numVotes.Length; i++)
{
if (NumVotes[i] > max)
{
max = NumVotes[i];
}
}
Console.WriteLine(max);
}
}
from the code its not clear, how you are initializing you election class instance, and how you are calling findWinner method. And yes your Do-While looping doing nothing. Because you already set the name array length as 5 so it will run the for loop once and then it will exit. even if you remove your do-while you will get the same output.
check the fiddle your code is working fine. I just assume you are creating instance of Election and then passing it to ElectionUI class to use it.
https://dotnetfiddle.net/oiVK9g
using System;
using System.Linq;
public class Program
{
public static void Main()
{
var ele = new Election();
var ui = new ElectionUI(ele);
ui.candidateInfo();
ele.findWinner();
}
}
class ElectionUI
{
Election theElection;
public ElectionUI(Election obj)
{
theElection = obj;
}
public void candidateInfo()
{
do
{
for (int i = 0; i < theElection.CandidateNames.Length; i++)
{
Console.Write("Please enter the name for Candidate #" + (i +
1) + ": ");
theElection.CandidateNames[i] = Console.ReadLine();
Console.Write("Please enter the number of votes for: {0}: ",
theElection.CandidateNames[i]);
theElection.NumVotes[i] = int.Parse(Console.ReadLine());
Console.WriteLine("");
}
} while (theElection.NumVotes.Length < 5);
}
}
class Election
{
private string[] candidateNames = new string[5];
private int[] numVotes = new int[5];
//get/set Candidate Names
public string[] CandidateNames
{
get { return candidateNames; }
set { candidateNames = value; }
}
//Get/Set Candidate votes
public int[] NumVotes
{
get { return numVotes; }
set { numVotes = value; }
}
public void findWinner()
{
int max = NumVotes.Max();
Console.WriteLine(max);
}
}
I think that you wanted to return the candidate name of who won, right?
Using your code you should change the findWinner method to:
public void findWinner()
{
int max = NumVotes.Max();
string winnerName = null;
for (var i = 0; i < numVotes.Length; i++) {
if (NumVotes[i] = max) {
winnerName = CandidateNames[i];
}
}
Console.WriteLine(winnerName);
}
You need to initialize the local variable max with Int32.MinValue. That way any value encountered will replace it.
In my Inputs class I have an array named score. I need to use it in my MathFun class and get the sum of it.
class Inputs
{
int amountgames;
public void AmountOfGames()
{
Console.WriteLine("How many games did you play?");
amountgames = int.Parse(Console.ReadLine());
}
public void Scores()
{
int[] score = new int[amountgames];
Console.WriteLine("score for game ");
for (int i = 0; i < score.Length; i++)
{
score[i] = int.Parse(Console.ReadLine());
}
Console.WriteLine("\nThe scores you entered are");
for (int j = 0; j < score.Length; j++)
{
Console.WriteLine(score[j]);
}
}
}
class MathFun
{
int number1;
int number2;
int total;
int averaged;
public int Average;
public int Added1;
public MathFun()
{
}
public void DivideThem()
{
Average = number1 / number2;
}
public void Added()
{
Added1 = inputs.score.sum();
//This is where in the array and its sum
}
public MathFun(int innumber1, int innumber2)
{
number1 = innumber1;
number2 = innumber2;
}
public int Number1
{
get
{
return number1;
}
set
{
number1 = value;
}
}
public int Number2
{
get
{
return number2;
}
set
{
number2 = value;
}
}
public int Total
{
get
{
return total;
}
}
public int Averaged
{
get
{
return averaged;
}
}
public void CalcTotal()
{
total = Added1;
averaged = Average;
}
}
You have two choices
Create an instance of Inputs that you can use in MathFun.
Make Scores() static, so that an instance is not required. If you do that, amountgames and AmountOfGames() will also have to become static.
Either way, you will have to return the inputs from Scores() or store them in some way in the class.
public int[] Scores()
{
int[] score = new int[amountgames];
Console.WriteLine("score for game ");
for (int i = 0; i < score.Length; i++)
{
score[i] = int.Parse(Console.ReadLine());
}
Console.WriteLine("\nThe scores you entered are");
for (int j = 0; j < score.Length; j++)
{
Console.WriteLine(score[j]);
}
}
return score;
}
Here's how you could approach it with the first approach
Inputs inputs = new Inputs();
int[] scores = Scores();
// Use scores with MathFun
NOTE: I would not generally create a function that is both responsible for writing scores out to the console and returning them. A single responsibility per method is preferred. The solution here is one that modifies your current code as little as possible.
Found my own solution
int sum = 0;
for (int i = 0; i < score.Length; i++)
{
sum += score[i];
}
add this to the array to add it all up
then just make an instance of sum
using System;
namespace Matrix_Algebra
{
public struct S_Matrix_size
{
public int size_R, size_C;
public S_Matrix_size(int r, int c)
{
this.size_R = r;
this.size_C = c;
}
}
public class C_Matrix_entries
{
public C_Matrix_entries()
{
int r, c;
Console.WriteLine("Enter number of rows and columns ");
r = Convert.ToInt32(Console.ReadLine());
c = Convert.ToInt32(Console.ReadLine());
S_Matrix_size size = new S_Matrix_size(r,c);
double[,] entry = new double [size.size_R,size.size_C];
Console.WriteLine("Enter the entries from first row [left to right] to the last row ");
for (int i = 0; i<size.size_R; i++)
{
Console.WriteLine("Enter the {0} row", i + 1);
for (int j = 0; j<size.size_C;j++)
{
entry[i, j] = Convert.ToDouble(Console.ReadLine());
}
}
}
}
}
namespace Row_Reduce_Algebra
{
using Matrix_Algebra;
public class TEST
{
static void Main()
{
C_Matrix_entries matrix_no1 = new C_Matrix_entries();
for (int i = 0; i < **matrix_no1.size**; i++)
{
}
}
}
}
As the title says, I'm trying to access a variable from a class instance, but don't know how to do it properly.
You can't access matrix_no1.size because size is inaccessible.
Add a public property to your C_Matrix_entries class, and reference it in Main().
public class C_Matrix_entries
{
public S_Matrix_size size { get; private set; }
public C_Matrix_entries()
{
...
size = new S_Matrix_size(r,c);
As #GrantWinney rightfully pointed out (as I was shaping up a working reply for you), you cannot access matrix_no1.size because it is inaccessible. (It is also out of scope being that matrix_no1 is a local variable declared in the default C_Matrix_entries constructor.)
Based on your code, here is an end-to-end working example of how to fix the problem using a somewhat different public property added to C_Matrix_entries. Beyond the flavor of the new S_Matrix_size public property you add to C_Matrix_entries (i.e. Grant Winney's will work too), you will need to compute the product of its size_R and size_C properties in your loop's setup.
using System;
namespace Matrix_Algebra
{
public struct S_Matrix_size
{
public int size_R, size_C;
public S_Matrix_size(int r, int c)
{
this.size_R = r;
this.size_C = c;
}
}
public class C_Matrix_entries
{
private S_Matrix_size _size;
public C_Matrix_entries()
{
int r, c;
Console.WriteLine("Enter number of rows and columns ");
r = Convert.ToInt32(Console.ReadLine());
c = Convert.ToInt32(Console.ReadLine());
_size = new S_Matrix_size(r,c);
double[,] entry = new double [_size.size_R,_size.size_C];
Console.WriteLine("Enter the entries from first row [left to right] to the last row ");
for (int i = 0; i<_size.size_R; i++)
{
Console.WriteLine("Enter the {0} row", i + 1);
for (int j = 0; j<_size.size_C;j++)
{
entry[i, j] = Convert.ToDouble(Console.ReadLine());
}
}
}
public S_Matrix_size Size { get { return _size; } }
}
}
namespace Row_Reduce_Algebra
{
using Matrix_Algebra;
public class TEST
{
static void Main()
{
C_Matrix_entries matrix_no1 = new C_Matrix_entries();
for (int i = 0; i < matrix_no1.Size.size_R * matrix_no1.Size.size_C; i++)
{
// TODO: something useful
Console.WriteLine(i); // FORNOW
}
}
}
}
class Sort
{
int[] arr;
int counter=0;
//Constructor
public Sort()
{
arr = new int[10000];
}
string address;
public void SwitchCase(int Case)
{
switch (Case)
{
case 1:
address = #"C:\Users\Aqib Saeed\Desktop\case1.txt";
break;
case 2:
address = #"C:\Users\Aqib Saeed\Desktop\case2.txt";
break;
case 3:
address = #"C:\Users\Aqib Saeed\Desktop\case3.txt";
break;
default:
break;
}
}
//Read file for input
public void FillArray()
{
using (StreamReader rdr = new StreamReader(address))
{
for (int i = 0; i < arr.Length; i++)
{
arr[i] = Convert.ToInt32(rdr.ReadLine());
}
}
}
// Insertion Sort
public void InsertionSort()
{
int insert;
for (int i = 1; i < arr.Length; i++)
{
insert = arr[i];
int moveItem = i;
while (moveItem > 0 && arr[moveItem - 1] > insert)
{
arr[moveItem] = arr[moveItem - 1];
moveItem--;
counter++;
}
arr[moveItem] = insert;
}
}
public void Counter()
{
Console.WriteLine(counter);
}
//Bubble Sorting
public void BubbleSort()
{
int temp;
for (int i = 0; i < arr.Length; i++)
{
for (int j = 0; j < arr.Length - 1 - i; j++)
{
if (arr[j] > arr[j + 1])
{
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
counter++;
}
}
}
}
//Selection Sorting
public void SelectionSort()
{
int min, temp;
for (int i = 0; i < arr.Length; i++)
{
min = i;
for (int j = i + 1; j < arr.Length; j++)
if (arr[j] < arr[min])
min = j;
temp = arr[i];
arr[i] = arr[min];
arr[min] = temp;
counter++;
}
}
// Write Output to file
public void Writer()
{
using (StreamWriter wrtr = new StreamWriter(#"C:\Users\AqibSaeed\Desktop\SortedOutput.txt"))
{
for (int i = 0; i < arr.Length; i++)
{
wrtr.WriteLine(arr[i]);
}
}
}
}
static void Main(string[] args)
{
Sort srt = new Sort();
Console.WriteLine("Enter Case 1 OR 2 OR 3");
srt.SwitchCase(Convert.ToInt32(Console.ReadLine()));
srt.FillArray();
srt.BubbleSort();
srt.Writer();
Console.WriteLine("Sorted Output File Is Ready");
srt.Counter();
Console.ReadLine();
}
I implement my Sort class for sorting integers and place int counter to determine number of swaps and comparsions. But I am not sure it is working correctly! Is there any other way to determine number of swaping and comparsions?
You could create a class which implements IComparable to count the comparator access and a specialized collection which counts the swaps. Like that you dont have to count the access inside of the sort algorithms and you delegate the tasks more strict to code parts.
In the index operator you count the swap operations and in the IComparable implementation you count the comparisons
Example for a class SortItem which implements the IComparable:
public class SortItem<T> : IComparable<T> where T : IComparable
{
private static int _ComparisonCount = 0;
public static int ComparisonCount
{
private set
{
_ComparisonCount = value;
}
get
{
return _ComparisonCount;
}
}
public T Value
{
get;
set;
}
public static void ResetComparisonCount()
{
_ComparisonCount = 0;
}
#region IComparable<T> Members
public int CompareTo(T other)
{
ComparisonCount++;
return this.Value.CompareTo(other);
}
#endregion
}
and the sorting collection:
public class SortCollection<T> : IList<SortItem<T>>
{
public SortCollection(IList<T> sortList)
{
InnerList = sortList;
}
private IList<T> InnerList = null;
public T this[int key]
{
get
{
return InnerList[key];
}
set
{
SwapCount++;
InnerList[key] = value;
}
}
private int _SwapCount = 0;
public int SwapCount
{
private set
{
_SwapCount = value;
}
get
{
return _SwapCount;
}
}
public void ResetSwapCount()
{
_SwapCount = 0;
}
}
Here the execution:
List<Int32> baseList = new List<int>(new Int32 {6, 2, 7, 3, 1, 6, 7 });
SortCollection<Int32> sortList = new SortCollection<int>(baseList);
//do the sorting....
Console.WriteLine("Swaps: " + sortList.SwapCount.ToString());
Console.WriteLine("Comparisons: " + SortItem<Int32>.ComparisonCount.ToString());
SortItem<Int32>.ResetComparisonCount();
sortList.ResetSwapCount();
You are only counting swaps and not counting comparisons. If you want to count comparisons then you need to add an extra counter that you increment every time you pass an if comparison.