They're bit-fields, an example being that unsigned int addr:9; creates an addr field 9 bits long.
It's commonly used to pack lots of values into an integral type. In your particular case, it defining the structure of a 32-bit microcode instruction for a (possibly) hypothetical CPU (if you add up all the bit-field lengths, they sum to 32).
The union allows you to load in a single 32-bit value and then access the individual fields with code like (minor problems fixed as well, specifically the declarations of code and test):
#include <stdio.h>
struct microFields {
unsigned int addr:9;
unsigned int cond:2;
unsigned int wr:1;
unsigned int rd:1;
unsigned int mar:1;
unsigned int alu:3;
unsigned int b:5;
unsigned int a:5;
unsigned int c:5;
};
union micro {
unsigned int microCode;
struct microFields code;
};
int main (void) {
int myAlu;
union micro test;
test.microCode = 0x0001c000;
myAlu = test.code.alu;
printf("%d\n",myAlu);
return 0;
}
This prints out 7, which is the three bits making up the alu bit-field.
They're bit-fields, an example being that unsigned int addr:9; creates an addr field 9 bits long.
It's commonly used to pack lots of values into an integral type. In your particular case, it defining the structure of a 32-bit microcode instruction for a (possibly) hypothetical CPU (if you add up all the bit-field lengths, they sum to 32).
The union allows you to load in a single 32-bit value and then access the individual fields with code like (minor problems fixed as well, specifically the declarations of code and test):
#include <stdio.h>
struct microFields {
unsigned int addr:9;
unsigned int cond:2;
unsigned int wr:1;
unsigned int rd:1;
unsigned int mar:1;
unsigned int alu:3;
unsigned int b:5;
unsigned int a:5;
unsigned int c:5;
};
union micro {
unsigned int microCode;
struct microFields code;
};
int main (void) {
int myAlu;
union micro test;
test.microCode = 0x0001c000;
myAlu = test.code.alu;
printf("%d\n",myAlu);
return 0;
}
This prints out 7, which is the three bits making up the alu bit-field.
It's a bit field. The number after the colon is how many bits each variable takes up.
arrays - What does ** do in C language? - Stack Overflow
c++ - What's the difference between * and & in C? - Stack Overflow
Could someone explain the use of the asterisk * in C and how it is used?
The C in DC already stands for Comics, so why we call it DC "comics" : BatmanArkham
Videos
They're bit-fields, an example being that unsigned int addr:9; creates an addr field 9 bits long.
It's commonly used to pack lots of values into an integral type. In your particular case, it defining the structure of a 32-bit microcode instruction for a (possibly) hypothetical CPU (if you add up all the bit-field lengths, they sum to 32).
The union allows you to load in a single 32-bit value and then access the individual fields with code like (minor problems fixed as well, specifically the declarations of code and test):
#include <stdio.h>
struct microFields {
unsigned int addr:9;
unsigned int cond:2;
unsigned int wr:1;
unsigned int rd:1;
unsigned int mar:1;
unsigned int alu:3;
unsigned int b:5;
unsigned int a:5;
unsigned int c:5;
};
union micro {
unsigned int microCode;
struct microFields code;
};
int main (void) {
int myAlu;
union micro test;
test.microCode = 0x0001c000;
myAlu = test.code.alu;
printf("%d\n",myAlu);
return 0;
}
This prints out 7, which is the three bits making up the alu bit-field.
So I know roughly how pointers work. You have a value, say char x, and doing char* x isn't the actual content of the variable but rather the physical address it's located at.
But the thing that really confuses me is where we use "&" versus "*". I know "&" corresponds to the memory location of something, but isn't that what the pointer operator does? Just gives you the memory address of a variable? When exactly do we use "&" and "*"?
Is the pointer operator just for defining pointer "objects" (in a sense) while the ampersand is done as a way of reading a memory address versus operating with it?
In C, arguments are passed by values. For example if you have an integer varaible in main
int main( void )
{
int x = 10;
//...
and the following function
void f( int x )
{
x = 20;
printf( "x = %d\n", x );
}
then, if you call the function in main like this
f( x );
then the parameter gets the value of variable x in main. However the parameter itself occupies a different extent in memory than the argument. So any changes of the parameter in the function do not influence to the original variable in main because these changes occur in a different memory extent.
So how to change the varible in main in the function?
You need to pass a reference to the variable using pointers.
In this case the function declaration will look like
void f( int *px );
and the function definition will be
void f( int *px )
{
*px = 20;
printf( "*px = %d\n", *px );
}
In this case, the memory extent occupied by the original variable x is changed because, within the function, we get access to this extent using the pointer
*px = 20;
Naturally the function must be called in main like this
f( &x );
Take into account that the parameter itself that is the pointer px is a local variable of the function. That is, the function creates this variable and initializes it with the address of variable x.
Now let's assume that in main you declared a pointer for example the following way
int main( void )
{
int *px = malloc( sizeof( int ) );
//..
And the function is defined like
void f( int *px )
{
px = malloc( sizeof( int ) );
printf( "px = %p\n", px );
}
As parameter px is a local variable, assigning to it any value does not influence the original pointer. The function changes a different extent of memory than the extent occupied by the original pointer px in main.
How to change the original pointer in the function? Just pass it by reference!
For example
f( &px );
//...
void f( int **px )
{
*px = malloc( sizeof( int ) );
printf( "*px = %p\n", *px );
}
In this case, the value stored in the original pointer will be changed within the function because the function is using dereferencing, accessing the same memory extent where the original pointer was defined.
Q: what is this (**)?
A: Yes, it's exactly that. A pointer to a pointer.
Q: what use does it have?
A: It has a number of uses. Particularly in representing 2 dimensional data (images, etc). In the case of your example char** argv can be thought of as an array of an array of chars. In this case each char* points to the beginning of a string. You could actually declare this data yourself explicitly like so.
char* myStrings[] = {
"Hello",
"World"
};
char** argv = myStrings;
// argv[0] -> "Hello"
// argv[1] -> "World"
When you access a pointer like an array the number that you index it with and the size of the element itself are used to offset to the address of the next element in the array. You could also access all of your numbers like so, and in fact this is basically what C is doing. Keep in mind, the compiler knows how many bytes a type like int uses at compile time. So it knows how big each step should be to the next element.
*(numbers + 0) = 1, address 0x0061FF1C
*(numbers + 1) = 3, address 0x0061FF20
*(numbers + 2) = 4, address 0x0061FF24
*(numbers + 3) = 5, address 0x0061FF28
The * operator is called the dereference operator. It is used to retrieve the value from memory that is pointed to by a pointer. numbers is literally just a pointer to the first element in your array.
In the case of my example myStrings could look something like this assuming that a pointer/address is 4 bytes, meaning we are on a 32 bit machine.
myStrings = 0x0061FF14
// these are just 4 byte addresses
(myStrings + 0) -> 0x0061FF14 // 0 bytes from beginning of myStrings
(myStrings + 1) -> 0x0061FF18 // 4 bytes from beginning of myStrings
myStrings[0] -> 0x0061FF1C // de-references myStrings @ 0 returning the address that points to the beginning of 'Hello'
myStrings[1] -> 0x0061FF21 // de-references myStrings @ 1 returning the address that points to the beginning of 'World'
// The address of each letter is 1 char, or 1 byte apart
myStrings[0] + 0 -> 0x0061FF1C which means... *(myStrings[0] + 0) = 'H'
myStrings[0] + 1 -> 0x0061FF1D which means... *(myStrings[0] + 1) = 'e'
myStrings[0] + 2 -> 0x0061FF1E which means... *(myStrings[0] + 2) = 'l'
myStrings[0] + 3 -> 0x0061FF1F which means... *(myStrings[0] + 3) = 'l'
myStrings[0] + 4 -> 0x0061FF20 which means... *(myStrings[0] + 4) = 'o'
* and & as type modifiers
int ideclares an int.int* pdeclares a pointer to an int.int& r = ideclares a reference to an int, and initializes it to refer toi.
C++ only. Note that references must be assigned at initialization, thereforeint& r;is not possible.
Similarly:
void foo(int i)declares a function taking an int (by value, i.e. as a copy).void foo(int* p)declares a function taking a pointer to an int.void foo(int& r)declares a function taking an int by reference. (C++ only)
* and & as operators
foo(i)callsfoo(int). The parameter is passed as a copy.foo(*p)dereferences the int pointerpand callsfoo(int)with the int pointed to byp.foo(&i)takes the address of the intiand callsfoo(int*)with that address.
(tl;dr) So in conclusion, depending on the context:
*can be either the dereference operator or part of the pointer declaration syntax.&can be either the address-of operator or (in C++) part of the reference declaration syntax.Note that
*may also be the multiplication operator, and&may also be the bitwise AND operator.
funct(int a)
Creates a copy of a
funct(int* a)
Takes a pointer to an int as input. But makes a copy of the pointer.
funct(int& a)
Takes an int, but by reference. a is now the exact same int that was given. Not a copy. Not a pointer.
I am currently working on an assignment in C where we are required to make a stack by simply using pointers.
I know the line: int *ptr = &val; declares ptr to be a "pointer to"(which is my interpretation of what asterisk * means in C) the "address of" the integer variable val.
When I want to create a double pointer, or a pointer to a pointer, I do so like:
int **ptr_ptr = &ptr; By setting ptr_ptr to a "pointer to" the address of pointer ptr.
When we use the asterisk anywhere other than in a declaration, it is usually referred to as dereferencing that pointer (I think), and grabbing the value that the pointer actually points to. This goes against my intuition that an asterisk means "pointer to".
Could anybody explain the proper meaning of the asterisk in C? Is it just that it means different things depending on how it is used (i.e. in a declaration versus anywhere else)?
Thanks!