I'm currently reading Deitel's book How to program C#. There is chapter where passing an array as a parameter is discussed. The following piece of code is presented:
static void ModifyArray(int[] array2)
{
for (var counter = 0; counter < array2.Length; ++counter)
{
array2[counter] *= 2;
}
}
My questions are:
How does the compiler know the array2 length since it is not established?
Still, why is not there any compilation error since an array has been created without a associated length?
Even if passing an array without an explicit length is possible how can the condition "counter < array2.Length" be evaluated?
Many thanks,
Ivan
Let me start with a small correction your second question. In C#, declaring parameters in a method doesn't really "create" anything new. Parameters take in a variable, which leads me to answer your first question. The compiler knows the length of the array because it knows the length of whatever array is passed into the method when the method is called. For example:
int[] myArray = new int[] { 1, 3, 5, 7, 9 };
ModifyArray(myArray) // <- the compiler knows that myArray has length of 5
This should also help to answer your third question. Also, it wouldn't really make logical sense to have a method in which you could only pass an array of a specific length, because it would make the use case of the method much more specific. In summary, arrays as parameters don't need a length because the length will be known from the array which is passed into the method.
C# array has a default property which indicates length of the array.
Related
In C, if we have an array, we can pass it by reference to a function. We can also use simple addition of (n-1) to pass the reference starting from n-th element of the array like this:
char *strArr[5];
char *str1 = "I want that!\n";
char *str2 = "I want this!\n";
char *str3 = "I want those!\n";
char *str4 = "I want these!\n";
char *str5 = "I want them!\n";
strArr[0] = str1;
strArr[1] = str2;
strArr[2] = str3;
strArr[3] = str4;
strArr[4] = str5;
printPartially(strArr + 1, 4); //we can pass like this to start printing from 2nd element
....
void printPartially(char** strArrPart, char size){
int i;
for (i = 0; i < size; ++i)
printf(strArrPart[i]);
}
Resulting in these:
I want this!
I want those!
I want these!
I want them!
Process returned 0 (0x0) execution time : 0.006 s
Press any key to continue.
In C#, we can also pass reference to an object by ref (or, out). The object includes array, which is the whole array (or at least, this is how I suppose it works). But how are we to pass by reference to the n-th element of the array such that internal to the function, there is only string[] whose elements are one less than the original string[] without the need to create new array?
Must we use unsafe? I am looking for a solution (if possible) without unsafe
Edit:
I understand that we could pass Array in C# without ref keyword. Perhaps my question sounds quite misleading by mentioning ref when we talk about Array. The point why I put ref there, I should rather put it this way: is the ref keyword can be used, say, to pass the reference to n-th element of the array as much as C does other than passing reference to any object (without mentioning the n-th element or something alike)? My apology for any misunderstanding occurs by my question's phrasing.
The "safe" approach would be to pass an ArraySegment struct instead.
You can of course pass a pointer to a character using unsafe c#, but then you need to worry about buffer overruns.
Incidentally, an Array in C# is (usually) allocated on the heap, so passing it normally (without ref) doesn't mean copying the array- it's still a reference that is passed (just a new one).
Edit:
You won't be able to do it as you do in C in safe code.
A C# array (i.e. string[]) is derived from abstract type Array.
It is not only a simple memory block as it is in C.
So you can't send one of it's element's reference and start iterate from there.
But there are some solutions which will give you the same taste of course (without unsafe):
Like:
As #Chris mentioned you can use ArraySegment<T>.
As Array is also an IEnumerable<T> you can use .Skip and send the returned value. (but this will give you an IEnumerable<T> instead of an Array). But it will allow you iterate.
etc...
If the method should only read from the array, you can use linq:
string[] strings = {"str1", "str2", "str3", ...."str10"};
print(strings.Skip(1).Take(4).ToArray());
Your confusion is a very common one. The essential point is realizing that "reference types" and "passing by reference" (ref keyboard) are totally independent. In this specific case, since string[] is a reference type (as are all arrays), it means the object is not copied when you pass it around, hence you are always referring to the same object.
Modified Version of C# Code:
string[] strArr = new string[5];
strArr[0] = "I want that!\n";
strArr[1] = "I want this!\n";
strArr[2] = "I want those!\n";
strArr[3] = "I want these!\n";
strArr[4] = "I want them!\n";
printPartially(strArr.Skip(1).Take(4).ToArray());
void printPartially(string[] strArr)
{
foreach (string str in strArr)
{
Console.WriteLine(str);
}
}
Question is old, but maybe answer will be useful for someone.
As of C# 7.2 there are much more types to use in that case, ex. Span or Memory.
They allow exactly for the thing you mentioned in your question (and much more).
Here's great article about them
Currently, if you want to use them, remeber to add <LangVersion>7.2</LangVersion> in .csproj file of your project to use C# 7.2 features
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
i would like to know how i would go about finding the length of an array without the use of the array.length method rather what does the array.length method acheive?
I had some homework to complete some arbituary array sorting without the use of the array.length method and i was curious as to how c# finds the array length does it go through the array counting each non null value and returns a value or is there a specific memory value associated to an arrays length that can be accessed more out of curiosity then anything else i was just wondering what goes on behind the scenes of the length method
A really awful way but to cover all grounds this would work but I stronger discourage this.
int[] test = new int[10];
int count = 0;
try
{
for (; ; )
{
count++;
test[count].ToString();
}
}
catch (IndexOutOfRangeException ex)
{
}
Console.Write(count);
Console.ReadKey();
this would be one way:
int count = 0;
foreach (var item in YourArray)
{
count++;
}
count will hold how many items there are in the array.
EDIT:
Ofcourse i forgot if you cant use the dreaded Length property the you can use the Count() method.
You can use theArray.GetLength(0), but it's basically the same as using theArray.Length, just more verbose...
Getting length of the array without using the Array.Length property is nearly impossible.
Well, you can:
Use enumerators(in foreach statement or through LINQ) and count the elements they give to you, but it will
be just an indirection - ArrayEnumerator obviously uses
Array.Length internally.
Use unsafe code and get the length, because it is stored before the
actual data (4 or 8 bytes before the actual first element).
Probably you can even get some information from managed heap about
the array reference and calculate the length, but if it is
possible it will be a hack, and even if we somehow learn that memory
allocated for the array is 100 byte, we can't be sure that all this memory is used
PROPOSED SOLUTION:
But what has probably been meant is the use of array terminators, like '\0' chars C runtime uses to terminate its strings.
To use array terminators you just arbitrary select some value(usually greatest or smallest) and use it as an array terminator:
Int32[] data = new Int32[] {10, -5, 100, Int32.MinValue};
PrintDataWithoutLength(data, Int32.MinValue);
PrintDataWithoutLength<T>(T[] data, T terminator)
{
for(Int32 i = 0; !data[i].Equals(terminator) ; i++)
{
Console.WriteLine(data[i]);
}
}
I'm writing a program for homework, but I have stumbled upon a very hard problem for me.
Now, I'm pretty new to C#, so please bear with me. This may be really easy and obvious.
On-topic:
C# doesn't allow me to perform arithmetical operations on multidimensional array values:
if(map[0,1] - map[0,0] == 10)
This statement doesn't return a value, but instead throws me an error:
Object reference not set to an instance of an object.
You need to first declare the array. Example:
var map = new int[2,2];
creates a two-dimensional array with four integer elements.
the error sounds like you didn't initiate the values of the array
also don't forget that you took [,] arrays
int[,] example = new int[,] { {11,5}, {1,10} };//initiate the array
if (example[0,0]-example[1,0] == 10)
{
}
I have a prototype:
int[] medianFileter(int[] data);
and an array
int[] intVal = new int[5];
How can I pass the intVal to the prototype in C#?
Um, you just call it (assuming you've got a real implementation to call):
int[] result = medianFileter(intVal);
Note that any changes made to the array within the method will show up in intVal: you're not passing each of the integers individually, but a reference to the whole array.
(There could be some trickiness here due to your use of the word "prototype" - it's not standard C# terminology, so I'm not exactly sure what you mean. If you could clarify the question, that would help.)
On a side note, method names in .NET are usually Pascal-cased, so this should probably be:
int[] result = ApplyMedianFilter(intVal);
It's either I don't see some obvious weirdness here, or it's just usual function invocation:
int[] medianFiltered = medialFileter(intVal);
This is what you would do,
medianFileter(intVal);
What's the problem with:
medianFileter(intVal);
?
I've just started learning C# and in the introduction to arrays they showed how to establish a variable as an array but is seems that one must specify the length of the array at assignment, so what if I don't know the length of the array?
Arrays must be assigned a length. To allow for any number of elements, use the List class.
For example:
List<int> myInts = new List<int>();
myInts.Add(5);
myInts.Add(10);
myInts.Add(11);
myInts.Count // = 3
Use List<> to build up an 'array' of unknown length.
Use List<>.ToArray() to return a real array, and not a List.
var list = new List<int>();
list.Add(1);
list.Add(2);
list.Add(3);
var array = list.ToArray();
A little background information:
As said, if you want to have a dynamic collection of things, use a List<T>. Internally, a List uses an array for storage too. That array has a fixed size just like any other array. Once an array is declared as having a size, it doesn't change. When you add an item to a List, it's added to the array. Initially, the List starts out with an array that I believe has a length of 16. When you try to add the 17th item to the List, what happens is that a new array is allocated, that's (I think) twice the size of the old one, so 32 items. Then the content of the old array is copied into the new array. So while a List may appear dynamic to the outside observer, internally it has to comply to the rules as well.
And as you might have guessed, the copying and allocation of the arrays isn't free so one should aim to have as few of those as possible and to do that you can specify (in the constructor of List) an initial size of the array, which in a perfect scenario is just big enough to hold everything you want. However, this is micro-optimization and it's unlikely it will ever matter to you, but it's always nice to know what you're actually doing.
You can create an array with the size set to a variable, i.e.
int size = 50;
string[] words = new string[size]; // contains 50 strings
However, that size can't change later on, if you decide you need 100 words. If you need the size to be really dynamic, you'll need to use a different sort of data structure. Try List.
Use an ArrayList if in .NET 1.x, or a List<yourtype> if in .NET 2.0 or 3.x.
Search for them in System.Collections and System.Collections.Generics.
You might also want to look into Dictionarys if your data is unique, This will give you two columns to work with.
User name , Total bill
it gives you a lot of built in tools to search and update just the value.
var yummy = new List<string>();
while(person.FeelsHappy()) {
yummy.Add(person.GetNewFavoriteFood());
}
Console.WriteLine("Sweet! I have a list of size {0}.", list.Count);
Console.WriteLine("I didn't even need to know how big to make it " +
"until I finished making it!");
try a generic list instead of array
In a nutshell, please use Collections and Generics.
It's a must for any C# developer, it's worth spending time to learn :)
As detailed above, the generic List<> is the best way of doing it.
If you're stuck in .NET 1.*, then you will have to use the ArrayList class instead. This does not have compile-time type checking and you also have to add casting - messy.
Successive versions have also implemented various variations - including thread safe variants.
If you really need to use an array instead of a list, then you can create an array whose size is calculated at run time like so...
e.g i want a two dimensional array of size n by n. n will be gotten at run time from the user
int n = 0;
bool isInteger = int.TryParse(Console.ReadLine(), out n);
var x = new int[n,n];