I am using gcc 4.8.1 and I am unable to understand output of following program.
#include<stdio.h>
int main()
{
char* a, b, c;
int* d, e, f;
float* g, h, i;
printf("Size of a %zu and b %zu and c %zu \n", sizeof(a), sizeof(b), sizeof(c));
printf("Size of d %zu and e %zu and f %zu and int is %zu \n", sizeof(d), sizeof(e), sizeof(f), sizeof(int*));
printf("Size of g %zu and h %zu and i %zu and float is %zu \n", sizeof(g), sizeof(h), sizeof(i), sizeof(float));
return 0;
}
Output is
Size of a 4 and b 1 and c 1
Size of d 4 and e 4 and f 4 and int is 4
Size of g 4 and h 4 and i 4 and float is 4
My question is why b and c are not char* type whereas same is possible in case of int and float. I want to know about how C grammar splits declarations.
In a declaration like
char* a, b, c;
Only the type char is used for all variables, not whether it is a pointer (* symbol). When used like that this (equivalent) syntax makes it more clear:
char *a, b, c;
To define 3 pointers:
char *a, *b, *c;
Or in cases where multiple pointers to char are often used, maybe do a typedef:
typedef char* char_buffer;
char_buffer a, b, c;
The problem is that you are using a bad style of declarations
These declarations
char* a, b, c;
int* d, e, f;
float* g, h, i;
are equivalent to
char* a;
char b, c;
int* d;
int e, f;
float* g;
float h, i;
sizeof an object of type char is equal to 1 while sizeof( char * ) in your system is equal to 4. So you get correct output
Size of a 4 and b 1 and c 1
As sizeof( int ) and sizeof( float ) in your system is equal to 4 then you get output
Size of d 4 and e 4 and f 4 and int is 4
Size of g 4 and h 4 and i 4 and float is 4
I said that you use bad style of programming because the declarations you are using like this
char* a, b, c;
do not consistent with the C grammar. The C grammar splits declarations in declaration specifiers (for the statement above it is keyword char) and declarators (in statement above they are *a, b, and c ). So you should follow the C grammar. In this case your code will be more clear.
char *a, b, c;
(Compare for example
char unsigned* c;
and
char unsigned *c;
What declaration is more clear?)
Do not forget that your code can read programmers that for example do not know C but know C#. In this case they will be simply confused. They will consider the declarations in the wrong way as you considered them in your post.
The only pointers in your program are a, d, and g.
It just happens that on your platform that int *, float *, int, and float all have the same size.
char* a, b, c;
*a is a char (when a itself is valid)
b is a char
c is a char
char* a, b, c;
here, a is of type char *, b and c are of type char. same goes for others also.
It is the case in your platform, int and float takes 4 bytes, just as a size of pointer [means sizeof(int) and sizeof(float) is same as sizeof(int *) and sizeof(float *) , respectively] whereas, char is of size 1.
So, your sizeof(a) yields 4 [a being a pointer], when sizeof(b) gives 1 [b is of type char].
Don't be under the impression that e, f are int*. They are not.
Don't be under the impression that h, i are float *. Again,
they are not.
[too long for a comment]
Just for completeness: To define three char pointers (instead of one char pointer and two chars) I'd go for:
char * a; /* This is used to do ... */
char * b; /* This is used to do ... */
char * c; /* This is used to do ... */
You need to put a separate asterisk * for every pointer you want to delare (because the language grammar says so):
// declare 3 pointers
char *a, *b, *c;
To make this clearer (to myself) I prefer to put the asterisk directly before the variable name, and not directly after the type specifier.
// I prefer this:
char *d;
// instead of this:
char* e;
This does not become apparant with int and float on your machine because these happen to have the same size as their respective pointer types (4).
Related
What does the following declaration mean?
char *(*g(char a, int b))
So far, I know that,
char *(*g)(char, int)
declares a pointer to a function that returns a char *, and I can successfully assign a value to it, however I can't do the same with the first. Any hints?
It looks like a function g that takes two arguments (char a and int b) and returns char**.
The outer parenthesis looks working like ones in char** x = /* some value */; char y = *(*x);
As a proof, this code compiles:
char *(*g(char a, int b));
char** test(void) {
return g(0, 0);
}
The two lines of code in the question are very different:
char *(*g(char a, int b)) // #1
char *(*g)(char, int) // #2
In #2 you have added a ) just after the g and that really changes the meaning a lot.
The first one is simply a function with the name g. It's the same as
char **g(char a, int b) // #1 without the unnecessary ( ) pair
but number two is a function pointer variable with the name g.
That also explains why you can assign to g in case #2 but can't assign to g in case #1.
Also notice that #1 is a function returning pointer-to-pointer-to-char while #2 is a function-pointer to a function returning pointer-to-char
So the two lines of code are different in more than one aspect.
What does , char *(*g(char a, int b)) mean?
g as function (char, int) returning pointer to pointer to char
When you write :
char *(*g)(char, int);
g is a pointer to a function...
Is you've got several functions taking a character and an integer for parameters and returning a 'char *' you can assign either of these functions to this pointer..
Example :
char *function1(char c, int i) {
...
}
char *function2(char c, int i) {
...
}
when you declare a pointer like you can see below, it can point on either of the above functions :
char *(*g)(char, int);
You can write:
g = function1 ;
or:
g = function2 ;
And when you call the function using the pointer:
char *retVal = (*g)('a', 12) ;
It will call either function1 or function2 depending on the last function that was assigned to the pointer.
As for :
char *(*g(char a, int b))
This is equivalent to :
char **g(char a, int b)
considering operator () has precedence level 1 and operator * has precedence level 2, the parenthesis doesn't affect the evaluation order.
I want to use the C function called is_subsetOf() in two different ways:
Way 1: int* a and int* b are arrays with sizes >=2.
Way 2: int* a has size >=2, but int* b is only size 1, which means b is an int.
How can I force C to be okay with int* b being of size 1? Or is this not possible in C? An int IS an array of size 1??
int* is_in(int *left_hand, int n_l, int *right_hand, int n_r) {
int *get_bool;
get_bool = malloc(sizeof(int)*n_l);
for (int i=0; i<n_l; i++) {
if (is_subsetOf(right_hand, n_r, *(left_hand+i), 1)) {
*(get_bool+i) = 1;
}
}
return (get_bool);
}
int desc(const void *a, const void *b) {
return (*(int*)a - *(int*)b);
}
int is_subsetOf(int *a, int n_a, int *b, int n_b) {
qsort(a, n_a, sizeof(int), desc);
qsort(b, n_b, sizeof(int), desc);
int v = includes(a, n_a, b, n_b);
return(v);
}
Here are the messages I get from the compiler. It's just a warning, I know, but I'd like everything to be clean.
tmp.c: In function ‘is_in’:
tmp.c:73:47: warning: passing argument 3 of ‘is_subsetOf’ makes pointer
from integer without a cast [-Wint-conversion]
if (is_subsetOf(right_hand, n_r, *(left_hand+i), 1)) {
~~~~~~~~~^~~
tmp.c:37:39: note: expected ‘int *’ but argument is of type ‘int’
int is_subsetOf(int *a, int n_a, int *b, int n_b) {
int* a and int* b are arrays with sizes >=2.
No, they are pointers and they don't have any size. You probably meant that you pass arrays through them, but they are not arrays. Know that there is a difference.
An int IS an array of size 1
No, int a[1]; is an array of size 1; int a; is just int. But arrays can decay into pointers to their first element and variables have addresses, so this is correct:
int a[1];
int b;
int* ptr1 = a;//Points to the a[0]
int* ptr2 = &b;
Both are now same type and can be used in the same way. Of course you don't know if the int is followed by any more ints in memory, that kind of checking is up to the programmer (usually by passing the length param as you do). The following is the code you are actually looking for:
is_subsetOf(right_hand, n_r, left_hand+i, 1)
Pointers can be incremented, left_hand+i will point to the i-th int after the int to which left_hand currently points to. Again, validity of such pointer is up to programmer.
The compiler warning is quite important here, because *(left_hand+i) is of type int and the compiler warns that it will treat is as int*. Essentially looking that the value of int as an address to memory. That's not at all what you want and it is an error.
I m learning C programming and I have seen some code where folks use double pointers. I did some searching on stackoverflow from below but still have a teeny tiny question (Why use double pointer? or Why use pointers to pointers?)
In the code below, my question is I have not defined 'b' as **b. Now
when I try to do (*b) I`m getting a compile error. Isnt this *(*b) same as
*(address of c) because 'a' has address of 'c'.. Why do I need to define 'b' as **b to really get the value of 'c'?
#include <stdio.h>
int main()
{
int *a, *b, c;
c = 10;
a = &c;
b = &a;
printf("*a - %d\n *(*b): %d\n," , *a, *(*b));
return 0;
}
Help/explanation is really appreciated :)
EDIT : Thanks a lot guys for the explanation. Things are now clear :)
Here is a working code.
int main()
{
int *a, *b, c;
c=10;
a = &c;
b = a;
printf("*a - %d\n *(*b): %d\n,",*a, *(b));
return 0;
}
Pointers are aptly name: they "point" to locations in memory.
When you write *b, you tell the compiler that you are going to declaring a pointer of type integer so that it points to an integer.
When you use b = a, you tell the compiler that you are assigning the address of c to a as well. Actually, b is a pointer variable itself which is storing the address of an integer variable c. So, this way, you can assign the address of one variable to another pointer as well.
Now, Regarding your code,
int main()
{
int *a, **b, c; // just change it from *b to **b
c = 10;
a = &c;
b = &a;
printf("*a - %d\n *(*b): %d\n,",*a, *(*b));
return 0;
}
You need to specify the compiler that the pointer b is a pointer to a pointer variable by writing 2 *.When you write **b, you are telling the compiler that you are pointing to another pointer variable. Similarly, you can also have triple pointers and Quadrupled pointers as well.
Here is a link for your reference. http://www.c4learn.com/c-programming/c-double-pointer/
In your code, you have to do int **b; because:
a is a pointer-to-integer, since a = &c.
b is a pointer-to-(pointer-to-integer), since you wrote b = &a.
You can access the value of c using *b.. change your code littlebit..
#include <stdio.h>
int main()
{
int *a, *b, c;
c = 10;
a = &c;
b = a;
printf("*a :%d\n *b: %d\n,",*a, *b);
return 0;
}
*b,*a
defines that a and b are two pointer variable..
a=&c;
Assign the address of the variable c in pointer a.. & stand for address of operator.
b=a;
Copy the contains of a in b.. Now b also contain the address of c..
Print *a and *b.. *a and *b means contain of a and b. So *a and *b will print value of c..
You can also use **b.. **b means b is a pointer which stores address of another pointer variable..
In that case the code will be,
#include <stdio.h>
int main()
{
int *a, *b, c;
c = 10;
a = &c;
b = &a;
printf("*a :%d\n *b: %d\n,",*a, *(*b));
return 0;
}
a contains address of c and b contains address of a.. So, *a will print value of c..
As b is a double pointer we need *(*b) to access the contain of b.. *(*b) will also print the value of c..
This one is quite obviously a function pointer :
typedef int (* foobar) (int a, unsigned char *b, unsigned int c);
But what does this one do?
typedef int (foobar *) (int a, unsigned char *b, unsigned int c);
It produces a compiler error, at least in GCC 4.3:
foo.cpp:1: error: expected `)' before '*' token
Let us assume I have declared the variable 'i' of certain datatype (might be int, char, float or double) ...
NOTE: Simply consider that 'i' is declared and dont bother if it is an int or char or float or double datatype. Since I want a generic solution I am simply mentioning that variable 'i' can be of any one of the datatypes namely int, char, float or double.
Now can I find the size of the variable 'i' without sizeof operator?
You can use the following macro, taken from here:
#define sizeof_var( var ) ((size_t)(&(var)+1)-(size_t)(&(var)))
The idea is to use pointer arithmetic ((&(var)+1)) to determine the offset of the variable, and then subtract the original address of the variable, yielding its size. For example, if you have an int16_t i variable located at 0x0002, you would be subtracting 0x0002 from 0x0006, thereby obtaining 0x4 or 4 bytes.
However, I don't really see a valid reason not to use sizeof, but I'm sure you must have one.
It's been ages since I wrote any C code and I was never good at it, but this looks about right:
int i = 1;
size_t size = (char*)(&i+1)-(char*)(&i);
printf("%zi\n", size);
I'm sure someone can tell me plenty of reasons why this is wrong, but it prints a reasonable value for me.
This works..
int main() {
int a; //try changing this to char/double/float etc each time//
char *p1, *p2;
p1 = &a;
p2 = (&a) + 1;
printf("size of variable is:%d\n", p2 - p1);
}
int *a, *b,c,d;/* one must remove the declaration of c from here*/
int c=10;
a=&c;
b=a;
a++;
d=(int)a-(int)b;
printf("size is %d",d);
I hope that below code would solve your problem in c++ without using sizeof() operator
for any variables like (int, char, float, double, char, short and many more...)
here I take integer,
int a;
then
show it as byte addressable output,
cout<<(char *)(&a + 1) - (char *)(&a);
This should work.
#define xsizeof(x) (char *)(&x+1) - (char *)&x
Try this,
#define sizeof_type( type ) ((size_t)((type*)1000 + 1 )-(size_t)((type*)1000))
For the following user-defined datatype,
struct x
{
char c;
int i;
};
sizeof_type(x) = 8
(size_t)((x*)1000 + 1 ) = 1008
(size_t)((x*)1000) = 1000
This should give you the size of your variable
#define mySizeof(type) ((uint)((type *)0+1))
Program to find Size of the variable without using sizeof operator
#include<stdio.h>
int main()
{
int *p,*q;
int no;
p=&no;
printf("Address at p=%u\n",p);
q=((&no)+1);
printf("Address at q=%u\n",q);
printf("Size of int 'no': %d Bytes\n",(int)q-(int)p);
char *cp,*cq;
char ch;
cp=&ch;
printf("\nAddress at cp=%u\n",cp);
cq=cp+1;
printf("Address at cq=%u\n",cq);
printf("Size of Char=%u Byte\n",(int)cq-(int)cp);
float *fp,*fq;
float f;
fp=&f;
printf("\nAddress at fp=%u\n",fp);
fq=fp+1;
printf("Address at fq=%u\n",fq);
printf("Size of Float=%u Bytes\n",(int)fq-(int)fp);
return 0;
}
#define GET_SIZE(myvar) ((char)( ((char*)(&myvar+1) )- ((char*)&myvar) ))
#include<stdio.h>
#include<conio.h>
struct size1
{
int a;
char b;
float c;
};
void main()
{
struct size1 *sptr=0; //declared one pointer to struct and initialise it to zero//
sptr++;
printf("size:%d\n",*sptr);
getch();
}
Below statement will give generic solution:
printf("%li\n", (void *)(&i + 1) - (void *)(&i));
i is a variable name, which can be any data type (char, short, int, float, double, struct).