Why do I need asterisk before an array?
The splat operator (that is, the *
) turns what would otherwise be an array into a list for assignment within the hash. You have to give the []
operator an actual list to turn into the key/value pairs of a hash. See below for a link to a short description of the splat operator which actually can do this (unwind an array into a list) or the reverse (gather a list into an array).
The way you did it above, you give Hash[]
an odd number of items, namely a single array. (Think of what [[:first_name, 'Shane'], [:last_name, 'Harvie']].flatten
produces. It yields [:first_name, 'Shane', :last_name, 'Havie']
.) As the docs you quoted say, the []
operator must have an even number of elements. Note that the following (though useless) does work:
>> Hash[[[:first_name, 'Shane'], [:last_name, 'Harvie']].flatten, 1]
=> {[:first_name, "Shane", :last_name, "Harvie"]=>1}
(It's unclear to me why you don't get the "odd number of arguments for Hash" error when using the code you have above - as you do if you try Hash[1]
.)
A simpler example may make it clearer. First, passing in one item, an array. The opening up the array with *
to hand Hash[]
a list of items:
>> Hash[['foo', 'bar', 'bizz', 'buzz']]
=> {}
>> Hash[*['foo', 'bar', 'bizz', 'buzz']]
=> {"foo"=>"bar", "bizz"=>"buzz"}
You might also find this write-up about the splat operator and the double splat operator useful.
What is the meaning of the asterisk before an array key name in print_r
The asterisk indicates an Object. And it is protected. This is the reason why you can't access them.
What does a prefixed asterisk mean
This is the spread operator and it is required to pass an existing array to a vararg
function.
When we call a
vararg
-function, we can pass arguments one-by-one, e.g.asList(1, 2, 3)
, or, if we already have an array and want to pass its contents to the function, we use the spread operator (prefix the array with*
):
Simplified example from the documentation:
val a = arrayOf(1, 2, 3)
val list = listOf(-1, 0, *a, 4)
println(list)
Output:
[-1, 0, 1, 2, 3, 4]
Without the spread operator, the array itself would be added as a single element, resulting in a List<Serializable>
with 4 elements:
[-1, 0, [Ljava.lang.Integer;@31befd9f, 4]
What is the role of the asterisk before the parameter?
In python, an *
unrolls a list.
That way you can use a list as a set of arguments.
some_args = ['first', False, 3]
do_something(*some_args)
In your case, the following is unrolling a list comprehension.
*[np.arange(x) for x in a.shape]
Why is the asterisk used before the each variable name instead of after the type?
Intuitively, I would think that
int*
would act like any other data type
If you want to become comfortable with C, you may need to adjust your intuition! Types are at least a little bit complicated; in fact the type system is a lot like a little programming language of its own! int
is a type, but "pointer" is a meta-type. You can have pointers to anything, even pointers to pointers.
In other words, why is C designed so that each [pointer] variable needs an asterisk before it?
Because, as explained in several of the answers to that other question, the scheme is that a declaration contains a "base type" and then some "declarators". In the case of arrays, pointers, and functions, the "declarator" is a little sample of whatever thing is going to have the base type. If I say
int i;
the declarator is just i
, so I'm saying that i
is going to be an int
. No mystery there. But if I say
int a[10];
I'm saying that one element of the array I'm declaring — that is, when I later use the array by saying something like a[i]
— is going to be an int
. If I say
int f();
I'm saying that calling the function is going to return an int
.
Finally, if I say
int *ip;
I'm saying that when I take the contents of this pointer, using the expression *ip
, then what *ip
is going to be is an int
.
And of course I can string these together on the same line:
int i, a[10], f(), *ip;
Now, perhaps I'm just rehashing the answers at the other question, and not explaining why things were set up this way. The reason is that it makes it possible to declare arbitrarily-complicated derived types. We can have arrays, and pointers, and functions, and arrays of arrays, and pointers to arrays, and functions returning pointers, and pointers to functions, and arrays of pointers to functions, and functions returning pointers to functions, and types even more numerous and complicated than those, and they can all be declared (in a general and open-ended way) using the same sort of concise, punctuation-rich, unwordy syntax that C is famous for
I don't think it would have been possible to design a type system that could have expressed the concept of "array of pointers to functions" on the left, leaving you to just put the variable name on the right. Or, if you could design such a system, it would have been complicated and confusing and cumbersome to use, even more complicated and confusing than C's present scheme seems to you, with its odd combination of type names on the left, and declarators — with their mixture of names, asterisks, and other punctuation — on the right.
See also Question 1.21 in the C FAQ list.
Or, perhaps I lied. I just said, "I don't think it would have been possible to design a type system that could have expressed [complicated things] on the left, leaving you to just put the variable name on the right." But, in fact, C's typedef
facility lets you do precisely that, if you want to build up a complex type in stages.
For example, if you say
typedef int *pointer_to_int;
you have arranged that the identifier pointer_to_int
is not an actual variable of type int *
, but rather, a synonym for the type int *
. Having done that, you can declare several integer pointers at once, without having to re-type those pesky asterisks:
pointer_to_int p1, p2, p3; /* just like int *p1, *p2, *p3; */
And it works for more complicated types, too. I can say
typedef int *(*pointer_to_function_returning_pointer_to_int)();
and then do
pointer_to_function_returning_pointer_to_int x1, x2, x3;
at which point x1
, x2
, and x3
are all pointers to functions returning pointers to int
, just as if I'd said
int *(*x1)(), *(*x2)(), *(*x3)();
In fact, the CS50 course introduces a "handy" typedef
typedef char *string;
which makes the identifier string
be an alias for the type "pointer to char
", which allegedly makes it easier for beginners to declare lots of strings. Unfortunately, char *
isn't really C's One True String type, so the string
typedef probably causes as much confusion as it attempts to resolve. (Part of the problem is that pointers do not necessarily make good "opaque" types. If you're dealing with a pointer, you often need to know that you're dealing with a pointer, so hiding it behind a typedef doesn't help.)
Why some functions are prototyped with an asterisk?
Asterisk is a part of return type, so this function
char *strchr(const char *s, int c)
Returns char*
Also,
int *c;
is not a "pointer variable" to int, but a variable which stores int pointer (int*
)
Why is the asterisk before the variable name, rather than after the type?
What does asterisk before brackets on object creation mean in C++?
new HashEntry*[TABLE_SIZE]
allocates and constructs an array of TABLE_SIZE
elements, where each element is a HashEntry*
, i.e. a pointer to a HashEntry
.
A more modern C++ version of that would be:
private:
std::vector<std::unique_ptr<HashEntry>> table;
public:
HashMap() : table(TABLE_SIZE) {}
This avoids having to define your own destructor, and is generally safer.
Pointers in C: when to use the ampersand and the asterisk?
You have pointers and values:
int* p; // variable p is pointer to integer type
int i; // integer value
You turn a pointer into a value with *
:
int i2 = *p; // integer i2 is assigned with integer value that pointer p is pointing to
You turn a value into a pointer with &
:
int* p2 = &i; // pointer p2 will point to the address of integer i
Edit:
In the case of arrays, they are treated very much like pointers. If you think of them as pointers, you'll be using *
to get at the values inside of them as explained above, but there is also another, more common way using the []
operator:
int a[2]; // array of integers
int i = *a; // the value of the first element of a
int i2 = a[0]; // another way to get the first element
To get the second element:
int a[2]; // array
int i = *(a + 1); // the value of the second element
int i2 = a[1]; // the value of the second element
So the []
indexing operator is a special form of the *
operator, and it works like this:
a[i] == *(a + i); // these two statements are the same thing
Related Topics
Result.Credit_Card_Verification Is Returning Nil Even on Error in Braintree
Factory_Girl + Rspec Doesn't Seem to Roll Back Changes After Each Example
When to Use Self in Module's Methods
Robustly Call a Flaky API: Proper Error Handling with Net::Http
Result.Credit_Card_Verification Is Returning Nil Even on Error in Braintree
Date Range Facets with Sunspot in Ruby on Rails
Why Are My Thread Variables Intermittent in Rails
Twitter-Bootstrap-Rails Gem Workflow
How to Daemonize Rails Rake Task on Elastic Beanstalk Start Up
Installing Rails with Gem, Error Loading Command: Install Undefined Method 'Invoke_With_Build_Args'
Git Post-Receive Hook Not Running Bundle Install
Undefined Method When Accessing Hash Element
Rbenv and Bundler: "Bad Interpreter: No Such File or Directory"