LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 04-08-2008, 03:12 AM   #1
Goblin_C_Noob
Member
 
Registered: Sep 2005
Posts: 48

Rep: Reputation: 15
Pointers in C


welcome to the newbiest question you are likely to read on these forums, please hold all flaming/bashing till the end of the question, and thank you for reading.

i am an intermediate java programmer who has moved onto trying to dabble in C and i just cant get my head around when, where, and how to use pointers.

What i know:
A pointer object contained the memory address for another object, not the object's value itself.
int * number; is a pointer of type int.
also, i know that to access the value inside the memory address held by number, i have to use an '&' in some way shape or form.

here's what i want to know to start with:

how do i properly assign and access the value in the memory address stored in number?

and how do i pass this pointer to a functions so that i can assign and access the values held in the memory address stored in number?

ok, flame away guys.
 
Old 04-08-2008, 04:34 AM   #2
Hko
Senior Member
 
Registered: Aug 2002
Location: Groningen, The Netherlands
Distribution: Debian
Posts: 2,536

Rep: Reputation: 111Reputation: 111
I think it is more correct to say that "int *number" makes number a variable of pointer-to-an-int type.
Code:
int integervar;
int *integerpointer; /* can contain a mem-address where an integer is stored. */

integervar = 7;
integerpointer = &integervar; /* integerpointer contains the address where the value of integervar is stored in memeory */

/* access the integer value of the memory location by dereferencing with a '*' (not a & as you mentioned. A '&' works the other way: it takes the address of some variable. */
*integerpointer = *integerpointer + 1; /* this will change the integer in memory, so integertvar  will be 6 now.
 
Old 04-08-2008, 05:51 AM   #3
ta0kira
Senior Member
 
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 3,078

Rep: Reputation: Disabled
I think a lot of your confusion is seeing things in the way of Java: as objects. There are really no "objects" in C. Just a bunch of memory with different labels used to denote different segments of it. For example, int one = 1; "creates" an int by placing it on the stack. Future uses of one are merely references to that location for the purposes of the operation. For example, one + 2; tells the compiler to add the number stored in the memory one represents with 2, but one is not really an object. A lot of C functions need to change the value of a specific variable so that, for example, future uses of the label one give you 2. This is not possible if you pass one as a function argument itself: doing so would be to say "use the number represented there," so by using &one you provide the pointer, which says "use the memory area of a place that represents a number." To convert it back to an area that represents a number, you use * on the left of the pointer. This allows you to either use the value or assign it a new one, just as if you were using one itself.
ta0kira
 
Old 04-08-2008, 04:39 PM   #4
Goblin_C_Noob
Member
 
Registered: Sep 2005
Posts: 48

Original Poster
Rep: Reputation: 15
ok before i go on, i'd like to make sure you all know, this is for an assignment, i dont want ppl thinking i tricked you all into helping me, not my intent. I decided i wanted a change from Java so i enrolled in C and C++ but my lecturer isn't the clearest guy around, and im in a tutorial class as one of 25 ppl, we are split between 2 instructors, not much help to be gained there.

but im starting to get this now, '&' grabs the memory address of the variable, while '*' jumps down and grabs the value stored at the memory address pointed at by the pointer.

so how would this work with structs, unions and array?

say i had:

Code:
typedef struct employee job1
{
char *name = (*char)malloc(sizeof(*char) * 10);
int id;
double salary;
}

job1 employee[10];

int *ptr = &employee[0]
is this correct so far, and how send the pointer to another function so that i can manipulate the data held in the struct?
 
Old 04-08-2008, 06:11 PM   #5
SciYro
Senior Member
 
Registered: Oct 2003
Location: hopefully not here
Distribution: Gentoo
Posts: 2,038

Rep: Reputation: 51
Umm, i do believe you cant use static assessments within a definition of a struct. That malloc will have to go.

C is statically typed, yet 'employee' is declared as 'job1', then latter you try to pass it to a 'int' typed pointer. Since 'job1' is declared as a struct, the 'ptr' variable will end up pointing to garbage, not to mention the compiler warning or error.

A pointer is a type whos VALUE is a memory address. When you pass variables to a function, what really gets passed is the VALUE of those variables. So in the case of a pointer, you pass the memory address it points to, so there is no trick involved. Since its a memory address you passed, that function can then alter the memory at that address, just like any other code. All thats necessary is to declare the variable in the function definition as a pointer, then pass the pointer just as you would a number, or any other type.
 
Old 04-08-2008, 06:32 PM   #6
cetialphav
Member
 
Registered: Sep 2003
Location: Raleigh, NC, USA
Distribution: Fedora
Posts: 88

Rep: Reputation: 16
Here is some code based on your example that shows some correct usage of pointers with structures and arrays. Hope this helps. If you see anything here that you don't understand, just ask. There are plenty of people here that can explain everything here.

Code:
typedef struct 
{
    char *name;
    char name2[];
    int id;
    double salary;
} employee;

employee employeeList[10];

initEmployee(employee *e) {
    e->name = (char *) malloc(10);
    e->name[0] = '\0';
    e->name2 = (char *) malloc(10);
    e->name2[0] = '\0';
    e->id = 0;
    (*e).salary = 0;
}
initEmployee( &(employeeList[5]) );
initEmployee( employeeList + 6 );
 
Old 04-08-2008, 06:45 PM   #7
Goblin_C_Noob
Member
 
Registered: Sep 2005
Posts: 48

Original Poster
Rep: Reputation: 15
ok, sweet;

you cant initialize anything inside a struct. CHECK.
employeeList is an array of type employee, which is a struct. CHECK.
'(*e)' is the same as 'e->'. CHECK.

Questions:
why are '(*e)' and 'e->' used? is it because 'e' is a pointer and we need to augment the values held by the memory address held in 'e'?

other than that i think im getting it.

initEmployee( &(employeeList[5]) );

is taking the value of employeeList[5] and finding the memory address it is stored in then ending that to initEmployee to be caught by a pointer.

and because elements in arrays are stored in consecutive memory address' employeeList + 6 is the same as saying employeeList[5].
 
Old 04-08-2008, 07:14 PM   #8
cetialphav
Member
 
Registered: Sep 2003
Location: Raleigh, NC, USA
Distribution: Fedora
Posts: 88

Rep: Reputation: 16
Since e is defined as being a pointer to an employee (employee *e), then you must dereference the pointer to get to the actual employee structure. That is why *e and e-> are used.

employeeList + 6 is actually the same as employeeList[6], which is the same as 6 + employeeList, which is the same as saying 6[employeeList]. (Seriously, that works and is completely legal.) Arrays are nothing more than syntactical sugar around pointer arithmetic. So the address of the entire array is &employeeList. The address of the first element of the array is &(employeeList[0]), which is the same as &(employeeList + 0), which is the same as &employeeList. So the name of the array is the address of it's first element.

You can actually initialize an array at declaration. The thing is that your code does not create an employee struct; it creates a new type called employee that is a struct. It does not make sense to initialize a type. Lots of people get confused about what a typedef really means.

One way that makes this easier to grasp is to run some simple code like this in a debugger like gdb. Then at the gdb prompt you can type in expressions like:
Code:
print employeeList
print employeeList[0]
print &employeeList[0]
And it will show you what it is. It becomes obvious what is a pointer and what is the actual value. This really gets handy when you have complex things like pointers to pointers to structures which contain pointers to pointers and you are trying to make sure you are grabbing the correct thing.
 
Old 04-08-2008, 07:29 PM   #9
Goblin_C_Noob
Member
 
Registered: Sep 2005
Posts: 48

Original Poster
Rep: Reputation: 15
the scary thing is, i actually understand what you are saying, thanks alot guys, you all really helped.

C here i come.
 
Old 04-08-2008, 07:43 PM   #10
Goblin_C_Noob
Member
 
Registered: Sep 2005
Posts: 48

Original Poster
Rep: Reputation: 15
oh wait, last thing;

say i want to change the values in multiple elements of the array without having to pass each element into the function one at a time.

can i just say

initEmployee( employeeList );

/*to be caught by*/

initEmployee(employee *e)
{}

and then in the function initEmployee can i say e++; to iterate to the next array element, cause 'e' stores the memory address of the Array?

Last edited by Goblin_C_Noob; 04-08-2008 at 07:44 PM.
 
Old 04-08-2008, 09:00 PM   #11
cetialphav
Member
 
Registered: Sep 2003
Location: Raleigh, NC, USA
Distribution: Fedora
Posts: 88

Rep: Reputation: 16
Yep, that is perfectly legal. Just be careful not to ++ past the end of the array. Unlike java, C will not give you a nice exception if you write past the end of the array. It will just quietly write over whatever happens to be there. So you have to be sure that you know how long the array is. That generally means adding an arrayLength parameter to the function so that the caller can pass in the number of elements in the array.
 
Old 04-09-2008, 01:49 PM   #12
osor
HCL Maintainer
 
Registered: Jan 2006
Distribution: (H)LFS, Gentoo
Posts: 2,450

Rep: Reputation: 78
Quote:
Originally Posted by cetialphav View Post
Code:
typedef struct 
{
    char *name;
    char name2[];
    int id;
    double salary;
} employee;
Let me point out that the above is not valid C or C++. In C, no struct member (except possibly the last) may have incomplete type. In C++, when an array is used as the type of a nonstatic member all dimensions shall be specified.
 
Old 04-09-2008, 04:03 PM   #13
Goblin_C_Noob
Member
 
Registered: Sep 2005
Posts: 48

Original Poster
Rep: Reputation: 15
Quote:
Originally Posted by osor View Post
Let me point out that the above is not valid C or C++. In C, no struct member (except possibly the last) may have incomplete type. In C++, when an array is used as the type of a nonstatic member all dimensions shall be specified.
so what are you saying?
 
Old 04-09-2008, 04:18 PM   #14
SciYro
Senior Member
 
Registered: Oct 2003
Location: hopefully not here
Distribution: Gentoo
Posts: 2,038

Rep: Reputation: 51
He is saying that if you have a array in a struct, you MUST say how big it is, or, it MUST be the last member of the struct. This is kind of silly, because you can just use a pointer instead, but i guess if you say its a array of unknown length, the compiler expects a array to be there, but will not know how big much space to allocate for it. So, if you need a array of unknown size in a struct, use a pointer instead.
 
Old 04-09-2008, 04:50 PM   #15
Goblin_C_Noob
Member
 
Registered: Sep 2005
Posts: 48

Original Poster
Rep: Reputation: 15
Quote:
Originally Posted by SciYro View Post
He is saying that if you have a array in a struct, you MUST say how big it is, or, it MUST be the last member of the struct. This is kind of silly, because you can just use a pointer instead, but i guess if you say its a array of unknown length, the compiler expects a array to be there, but will not know how big much space to allocate for it. So, if you need a array of unknown size in a struct, use a pointer instead.
so you're saying

Code:
typedef struct
{
char Name[30]
int id
}employee

employee EmployeeList[10];
is correct?

what about if you have to use malloc and assign memory at compile time?
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
pointers erat123 Programming 8 06-14-2007 11:54 PM
pointers in c++ marios_auth Programming 1 06-16-2004 08:20 AM
Pointers Pointers Pointers urzumph Programming 9 03-11-2004 09:49 AM
Looking for some pointers... p3ngu!n Linux - Newbie 17 10-30-2003 06:46 AM
need help with pointers qanopus Programming 8 02-03-2003 05:09 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 08:34 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration