[Tutorial] Ellipsis Operator (" . . . ")
#1

Introduction

You can use this while prototyping [prototyping in Dev-C++ would be: void SomeFunction(arguments); (or void SomeFunction(args) { CODE; }) and in Pawn (SA-MP) will be something like: stock SomeFunction(arguments); (or stock SomeFunction(args) { CODE; })]. This can be used in 'Function Prototyping'.

The concept.

Functions.

As I said, it can be used in function prototyping. Why? because it is used for a purpose, and the purpose would be set the function's ability to have unknown number of arguments.

An average scripter would know 'how to make a function with stock' and with arguments. But what if he wants to declare the number of arguments to unknow. For example; you make a function:

pawn Code:
stock Sum(num1, num2)
{
    new result = 0;
    result = num1 + num2;
    return result;
}
Here is the function example, now, you can use this to add ONLY two numbers. You can only fill two arguments with integers. But when you think about having more than two arguments, some of you would add one more arguments in the prototype of the function [stock Sum(num1, num2, num3)]. And the more you need, the more you keep adding arguments. But you dont need to keep doing this! Well there is "The Ellipsis operator". It is actually just the combination of three dots (" . . . "). You can use this while prototyping the function if you want number of arguments to be unknown. Using "stock Sum(num1, num2)" would have limitations! And the limitations are: you cant have more than two arguments. Means that when you use Sum();, you cant set the number of arguments more than two (depends what have you done with the function prototype). Writing Sum(1, 5); would return 6. But with the prototype having limitations would not allow you to write Sum(2, 5, 6); [Or more than three arguments.] and the compiler would result errors/warnings. Now, if you include the three dots in your prototype, it would be something like this:

pawn Code:
stock Sum(...)
{
    new result = 0;
    for (new i = 0; i < numargs(); ++i)
    {
        result += getarg(i) ;
    }
    return result;
}
This actually is used for no limitations for arguments. It can be used but with many arguments which arent even declared in the function prototype. It can be used like this:

pawn Code:
main()
{
    printf("%i", Sum(1, 5, 7, 7)); // Will result 20. You can also do Sum(1,5,14,14,6,3,22,88); That will give 153
}

stock Sum(...)
{
    new result = 0;
    for (new i = 0; i < numargs(); ++i)
    {
        result += getarg(i);
    }
    return result;
}
You can also add argument(s) in the prototype [stock Sum(arg, arg2, ...) { CODE; }].

Arrays.

Now you have gone through 'Functions'. Its also available in arrays. Here is a simple example:

pawn Code:
new EllipsisArray[5] = {5, ...};
Now let me explain the above array given. We create an array whose ability is to hold 5 slots of data. And as you can see that the example I gave above also declares what will the slot '0' hold. It holds the integer 5. On the right hand side, separated with the comma, comes the Ellipsis Operator (" . . . "). Now for those who dont know what does it do; it actually sets the data for all the slots as same as set for the slot '0'. Easily, it sets the data for all the data slots which is declared before it. In the example, 5 is declared before the operator. Now what will happen is that the image of the data would be: EllipsisArray[0] = 5, [Ellipsis Operator Starts from here]: EllipsisArray[1] = 5, EllipsisArray[2] = 5, EllipsisArray[3] = 5, EllipsisArray[4] = 5.

Here is an image:


All the slots contain the integer 5. [Dont think about the C-Syntax. Its just 'int' in shot]

If you are still not satisfied reading this; you can try this:

pawn Code:
new EllipsisArray[5] = {5, ...};

main()
{
    printf("%i\n%i\n%i\n%i\n%i", EllipsisArray[0], EllipsisArray[1], EllipsisArray[2], EllipsisArray[3], EllipsisArray[4]);
}
And the output will be:
Code:
5    // EllipsisArray[0] holds five.
5    // EllipsisArray[1] holds five.
5    // EllipsisArray[2] holds five.
5    // The same will be for the data slots 3 and 4 
5
But if you add another argument, it wont do as you expect. Here is an Example:

pawn Code:
new EllipsisArray[5] = {5, 6, ...};

main()
{
    printf("%i\n%i\n%i\n%i\n%i", EllipsisArray[0], EllipsisArray[1], EllipsisArray[2], EllipsisArray[3], EllipsisArray[4]);
}
The output will be:
Code:
5
6
7
8
9
Because it adds one then keeps going on.

Now some of you might be confused, what if you add an argument, not equal to 6, but to any number, like 8. Here is the example:

pawn Code:
new EllipsisArray[5] = {5, 8, ...};
Confused, ha? Its easy to understand. First we give give the number 5 to the slot '0', then we give the number 8 to the slot '1', then we put the Ellipsis Operator to do its work. Here is the test code:

pawn Code:
new EllipsisArray[5] = {5, 8, ...};

main()
{
    printf("%i\n%i\n%i\n%i\n%i", EllipsisArray[0], EllipsisArray[1], EllipsisArray[2], EllipsisArray[3], EllipsisArray[4]);
}
The output will be:
Code:
5
8
11
14
17
Thaap! How can 11 come after 8? As ACI said it increases by 1? Well, I will explain you in a mathematical way:

First is 5. Second comes 8. Then what the Ellipsis Operator does is that he subtracts 8 with 5 (8 - 5) the the answer he gets is 3. What he does then, he the takes the 3 and adds it to 8 ( 3 + 8 ), which results 11. Now, it might be clear how did 11 come from. Now what the Operator does is that he again adds 3 to 11 (3 + 11), which results 14. You can see how that came up. Then it again adds 3 to 14 (3 + 14), which gives 17. What a clear concept you gave me about that ACI!

But wait! here is another example of an array using Ellipsis Operator:

pawn Code:
new EllipsisArray[5] = { 10, 11, 34, ...};
And lets now see what would be the results if we test:

pawn Code:
// Yes, I have gone advanced in this example because its useless wasting time writing bunch of codes. It will be done by using a loop; 'for' loop.

new EllipsisArray[5] = { 10, 11, 34, ...};
main()
{
    for(new i = 0; i != 5; i++)
    {
        printf("%i", EllipsisArray[i]);
    }
}
And the output will be:

Code:
10
11
34
57
80
The two numbers 57 and 80 were not declared. But it got printed out when the system subtracted the last number with the second last number; 34 - 11, which results 23. If you have a problem in understanding, here are the numbers written in bold:

pawn Code:
new EllipsisArray[5] = { 10, [B]11[/B], [B]34[/B], ...};
After the system gets 23 by subtracting 34 with 11, the system would then take the number 23 and add it to 34, which is the last number (34 + 23). This will result 57. You do now see how 57 got printed? After printing 57, the system will take the number 23 and add it with 57 (57 + 23) (because 57 has been declared in the memory, so it will be considered as the last number declared). The result will be 80. Easy, yea?

Here is an another example of a different loop but would do the same as above:

pawn Code:
// 'do' loop;

new EllipsisArray[5] = { 10, 11, 34, ...};
main()
{
    new i = 0;
    do
    {
        printf("%i", EllipsisArray[i++]);
    } while i != 5;
}
The output will be the same as above.

Using Binary in Arrays.

If you want to have a basic concept of binary, then here is a video regarding this:

https://www.youtube.com/watch?v=0qjE...6AB973C6E39758

It only gives you a simple basic concept about binary, then, going for advanced, you need to visit this tutorial: https://sampforum.blast.hk/showthread.php?tid=177523

___________

For this section, you must at least have a basic concept of binary, and, you must have the concept of the Ellipsis Operator.

- Lets get started with this section, in this section, we'll be going not through numbers, but through binary. Here is an example of binary being used in the Ellipsis Operator:

pawn Code:
new EllipsisArray[5] = {0b1011, ...};

main()
{
    for(new i = 0; i < 5; i++)
    {
        printf("EllipsisArray[%i] = 0b%b", i, EllipsisArray[i]);
    }
}
The output in binary would be:

Code:
EllipsisArray[0] = 0b1011
EllipsisArray[1] = 0b1011
EllipsisArray[2] = 0b1011
EllipsisArray[3] = 0b1011
EllipsisArray[4] = 0b1011
As you know, it would put the same data before the Ellipsis data, because the data is set for all slots the same. Why? because there is no other argument in the initialization of the array, if there was, then it would result different binary numbers. Start reading from 'Arrays' if you want to know how the Ellipsis Operator yields different results IF there is also a argument more.

But, if we want the code to result as an integer, then the output will be:

Code:
EllipsisArray[0] = 11
EllipsisArray[1] = 11
EllipsisArray[2] = 11
EllipsisArray[3] = 11
EllipsisArray[4] = 11
Here is another example of an array using Ellipsis Operator:

pawn Code:
new EllipsisArray[5] = {0b1011, 0b101, ...};

main()
{
    for(new i = 0; i < 5; i++)
    {
        printf("EllipsisArray[%i] = 0b%b", i, EllipsisArray[i]);
    }
}
The output will be:

Code:
EllipsisArray[0] = 0b1011
EllipsisArray[1] = 0b101
EllipsisArray[2] = 0b11111111111111111111111111111111 - All 32-bits on.
EllipsisArray[3] = 0b11111111111111111111111111111001 - ?
EllipsisArray[4] = 0b11111111111111111111111111110011 - ?
Un-expected? Actually you will be thinking that it will result 6 in binary (0b0110) by doing 11 - 5. No, actually, adding, dividing, subtracting, multiplying, etc.. in this numerical system is different! But here, something is very different which I myself really didn't expect! In 'EllipsisArray[2]', maybe all the 32-bits are turned on. Then others have been left shifted.
__________________________________________________ ________

Here is what you should be aware of:
Code:
error 041: invalid ellipsis, array size is not known
The problem would be that you would have done something like this:

pawn Code:
new array[5] = {...}
Which is totally wrong. You need to declare something. That would not then give errors/warnings.

Case Ranges.

This thing popped up in my mind so I decided to add the Case Type section. Lets start, by this section, I mean we will be working on the 'case' thing with the two dots which looks like Ellipsis Operator. This may come useful to you in future. Now the syntax is the following:

pawn Code:
case /*something*/.../*something*/: /*code*/
//Eg:
case 0..9: SetPlayerHealth(playerid, 0.0);
This will do the same as:

pawn Code:
case 1: SetPlayerHealth(playerid, 0.0);
case 2: SetPlayerHealth(playerid, 0.0);
case 3: SetPlayerHealth(playerid, 0.0);
case 4: SetPlayerHealth(playerid, 0.0);
case 5: SetPlayerHealth(playerid, 0.0);
case 6: SetPlayerHealth(playerid, 0.0);
case 7: SetPlayerHealth(playerid, 0.0);
case 8: SetPlayerHealth(playerid, 0.0);
case 9: SetPlayerHealth(playerid, 0.0);
The advantage of using this is that you dont to have write more bulk of codes. Instead of doing that, it will be easy using the Ellipsis operator.

If you are having problems, you can send me a private message regarding this.
Reply


Messages In This Thread
Ellipsis Operator (" . . . ") - by ACI - 04.01.2014, 19:00
Re: Ellipsis Operator (" . . . ") - by ACI - 04.01.2014, 19:20
Re: Ellipsis Operator (" . . . ") - by ACI - 05.01.2014, 13:24
Re: Ellipsis Operator (" . . . ") - by Hansrutger - 05.01.2014, 13:36
Re: Ellipsis Operator (" . . . ") - by Vince - 05.01.2014, 17:38
Re: Ellipsis Operator (" . . . ") - by Patrick - 05.01.2014, 18:21
Re: Ellipsis Operator (" . . . ") - by ACI - 06.01.2014, 11:22
Re: Ellipsis Operator (" . . . ") - by Ada32 - 06.01.2014, 11:52
Re: Ellipsis Operator (" . . . ") - by ACI - 06.01.2014, 12:09
Re: Ellipsis Operator (" . . . ") - by Ballu Miaa - 06.01.2014, 12:23

Forum Jump:


Users browsing this thread: 1 Guest(s)