PDA

View Full Version : Really Hoping Someone Knows C Well...



Polizei
04-15-2008, 12:13 PM
I'm talking a programming class right now and pointers and arrays are really screwing me over. I have this one exercise where I need to take 2 arrays and add them element-wise and put that into a third array.

Example:
Array1 = {1, 2, 3, 4}
Array2 = {2, 3, 4, 5}

Add those element-wise to get:
Array3 = {3, 5, 7, 9}

I have started writing the program, but I can't figure out what to do to get the sums into a third array, nor sum them up. I am thinking using a for() loop and using an index to increase a pointer location, but it's confusing the hell out of me. This is what I have so far... hoping someone can point me in the right direction.


#include <stdio.h>
#pragma hdrstop
#include <conio.h>
//---------------------------------------------------------------------------
#pragma argsused
#define SIZE 5
int main (void){
const int Array1[SIZE]={3,5,7,9,11};
const int Array2[SIZE]={2,4,6,8,10};
int Array3[]={argc[]};

printf("This program adds two arrays, element-wise.\n");
printf("The first array is equal to {3,5,7,9,11}\n");
printf("The second array is equal to {2,4,6,8,10}\n");

printf("The third array is equal to:");

while(!kbhit());

return 0;

Thanks for any help. :) :yepp:

ARC1450
04-15-2008, 01:50 PM
Yeah, you're on the right track with a for{} loop.


for(x=0;x<SIZE;x++)
{
Array1[x] + Array2[x] = Array3[x];
}

At least I used to be able to do that back in the day. If it's valid now, I don't really know. But hopefully that can throw you in the right direction. And FWIW, that's the really, really, REALLY dirty way to do it.

G.Foyle
04-15-2008, 01:52 PM
Yeah, you're on the right track with a for{} loop.


for(x=0;x<SIZE;x++)
{
Array1[x] + Array2[x] = Array3[x];
}

At least I used to be able to do that back in the day. If it's valid now, I don't really know. But hopefully that can throw you in the right direction. And FWIW, that's the really, really, REALLY dirty way to do it.
Not precisely right (the bold line).


This is working code:

#include <stdio.h>
#define SIZE 5

int
main ()
{
const int array1[SIZE] = { 3, 5, 7, 9, 11 };
const int array2[SIZE] = { 2, 4, 6, 8, 10 };
int array3[SIZE];
int i;

printf ("This program adds two arrays, element-wise.\n");
printf ("The first array is equal to: \n");
for (i = 0; i < SIZE; i++)
{
printf ("&#37;i, ", array1[i]);
}

printf ("\nThe second array is equal to: \n");
for (i = 0; i < SIZE; i++)
{
printf ("%i, ", array2[i]);
}

for (i = 0; i < SIZE; i++)
{
array3[i] = array1[i] + array2[i];
}

printf ("\nThe third array is equal to: \n");
for (i = 0; i < SIZE; i++)
{
printf ("%i, ", array3[i]);
}
printf ("\n");
return 0;
}
Do you need anything explained?

ARC1450
04-15-2008, 01:56 PM
Baaaaah. . .

Okay, so I just had the order wrong. So sue me. :D

It's been almost 10 years since I touched C. Can't a guy get a break? :shrug: :p:

G.Foyle
04-15-2008, 01:58 PM
No problem man :) last time I coded in C was last year... I need to get back to some projects.

Polizei
04-15-2008, 02:10 PM
Do you need anything explained?

:clap:

No, don't need anything explained. The way I am with programming is, I can look at a working program and see how it works, but once I am tasked with writing my own, I can get half way there until I get stuck with the syntax of it. I know what needs to be done and some of the syntax to write it, but filling in the blanks is hard for me. Thanks! :up: :yepp:

Polizei
04-15-2008, 05:24 PM
I've got some more questions. I have another exercise here that asks me to take an array and copy the contents into two other pre-initialized arrays. The first copy must be made using array notation and the second copy made using pointer notation and pointer incrementing.

The exercise gave me some hints, but it seems like the hints only tell me what to call my functions.



double source[5] = { 1.1, 2.2, 3.3, 4.4, 5.5 };
double target1[5];
double target2[5];
copy_arr(source, target1, 5);
copy_ptr(source, target2, 5);


All of that seems like a different language to me... I don't understand most of it. I know the pointer notation and incrementing copies one element of the array at a time, but I don't remember learning any copy commands/functions.

Help? :confused:

Ouchy
04-16-2008, 12:16 AM
You copy the contents by looping through the pre-initialized arrays and assigning each empty element to the corresponding element in the source array. For one of them, you can use the array dereferencing method mentioned above. For the other one, you will use pointer arithmetic. This is also quite easy, you just increment the pointer by one for each element. Element 0 is the original pointer to the array.

Ex. Simple.




int arr[5];
int element_zero;
int element_one;

/* Element 0 */

element_zero = *arr;

/*
Lets increment the pointer by 1.
It knows that the pointer is to an int, so it will automatically
increment the pointer to the next int (4 bytes in our case). Great!
*/

arr++;

/* Element 1 */

element_one = *arr;

Polizei
04-16-2008, 05:54 AM
I don't understand? :confused: :(

G.Foyle
04-16-2008, 09:29 AM
copy_arr(double * source, double * target, int count)
and
copy_ptr(double * source, double * target, int count)
are functions that copy count first elements of source array to target array. I assume you have to write them.

What Ouchy said is that you can reference an element either by it's index, ie
a = array[3];
or by adding 3 to the pointer to that array:
a = array + 3;
pointer is a number, incrementing that number gives you pointer to next thing, and since array elements are stored directly after the previous one in memory, you can use pointer arithmetics.

Polizei
04-16-2008, 11:54 AM
Ok, don't laugh guys but I'm really having problems with this one. :eh:



#include <stdio.h>
#pragma hdrstop
#include <conio.h>
//---------------------------------------------------------------------------
#define SIZE 5
#pragma argsused
int main(int argc, char* argv[])
{
double source[SIZE]={ 4, 5, 6, 7, 8 };
double target1[SIZE];
double target2[SIZE];
int i;

printf("This program copies one array into 2 others using pointer notation");
printf(" and using array notation.\n\m");
printf("The source array is equal to: \n");
for (i = 0; i < SIZE; i++){
printf("%i, ", source[i]);
printf("\n\n");
}
printf("The first target array was created using pointer notiation\n");
printf(" and pointer incrementing.");
for (i = 0; i < SIZE; i++){
target1[i] = *source[i];
printf ("%i, ", target[i])


I know that doesn't work, but my question is, why, and is that pointer notation with pointer incrementing? :shrug:

No idea what to do with array notation. :confused:

This programming stuff is really not my cup of tea, which is why I dropped computer engineering and took up electrical engineering. Just trying to make it through this class. Thanks for the help guys. :up:

Ouchy
04-16-2008, 02:20 PM
Well, I don't want to give too many hints but you seem to be getting a bit off track. :)

Array notation is the exact same as you did above.

The reason your code doesn't work is because you are dereferencing a pointer to a double twice.

*source[i] should be source[i].
Now you are done the array copying one.

Now for pointer arithmetic you just add it.


double *temp;
for (i = 0; i < SIZE; i++) {
temp = target1 + i;
*temp = *(source + i);
}


What is temp? Temp is just a pointer to a memory address, we use it because we still want to maintain the original memory address of target1 (To easily print out target1). So we set the address of the corresponding element by adding i to it. We then look at our source array. We add i to it to increment the memory address. We are now pointing to another location in the array. If i is 1, we have source + 1, so we are pointing to source[i].

For your purposes you can think of array dereferencing and pointer arithmetic as the same thing.

array[3] = *(array + 3);

Why do we need the *? Array is a pointer to a memory address, it stores a 4 byte address in our machines. Ex. 0xb2fa0400. When we add 3 to it. We increment this address. However, we do not want the address, we want the value stored within it, so we dereference the memory address to get the value stored within. You can either dereference a memory address by using * or by array notation [], you can think of them as being the same.

m0da
04-16-2008, 08:59 PM
#include <stdio.h>

void copy_arr(double source[], double target1[], int size);
void copy_ptr(double source[], double target2[], int size);

int main()
{
double source[5] = { 1.1, 2.2, 3.3, 4.4, 5.5 };
double target1[5];
double target2[5];
copy_arr(source, target1, 5);
copy_ptr(source, target2, 5);
getchar();
return(0);
}

void copy_arr(double source[], double target1[], int size)
{
int i = 0;
printf("Target1 contains: ");
for (i = 0; i < size; i++)
{
target1[i] = source[i];
printf("&#37;g ", target1[i]);
}
printf("\n");
}

void copy_ptr(double *source, double *target2, int size)
{
int i = 0;
printf("Target2 contains: ");
for (i = 0; i < size; i++)
{
*(target2 + i) = *(source + i);
printf("%g ", *(target2 + i));
}
printf("\n");
}


merry christmas.
i'm in a C class right now as well... Just finished a programming assignment that involved linked lists and adding, multiplying, and evaluating polynomials we have to read from files... :(
thank god.

that code works btw, i just compiled it.

Polizei
04-16-2008, 09:48 PM
I was just going to come back and ask what the arguments meant in the copy_arr and copy_ptr functions... like, how they relate to the "guts" of the function.

Thanks m0da... going to try to pick it apart and figure out how it works. This upcoming test is going to kill me I think.

ZOMGVTEK
04-16-2008, 09:57 PM
oh god, the memories...

I just finished taking a cpp exam...

UGH that sucked.

Polizei
04-17-2008, 06:19 AM
Yup. My professor has gotten bad in the past couple weeks. He teaches us what the compiler/Windows does with the data, not how funtions and arguments work. Hence, me asking for help.

MuffinFlavored
04-17-2008, 01:01 PM
I'm talking a programming class right now and pointers and arrays are really screwing me over. I have this one exercise where I need to take 2 arrays and add them element-wise and put that into a third array.

Example:
Array1 = {1, 2, 3, 4}
Array2 = {2, 3, 4, 5}

Add those element-wise to get:
Array3 = {3, 5, 7, 9}




int main() {
int array_a[4] = {1, 2, 3, 4};
int array_b[4] = {5, 6, 7, 8};
int array_c[4];
int i = 0;

for (i = 0; i < 4; i++) {
printf("array_a[&#37;d] = %d\n", i, array_a[i]);
}

printf("\n");

for (i = 0; i < 4; i++) {
printf("array_b[%d] = %d\n", i, array_b[i]);
}

printf("\n");

array_c[0] = array_a[0];
array_c[1] = array_a[2];
array_c[2] = array_b[0];
array_c[3] = array_b[2];

for (i = 0; i < 4; i++) {
printf("array_c[%d] = %d\n", i, array_c[i]);
}

printf("\n");

system("pause");
return 0;
}

Calmatory
04-18-2008, 12:43 AM
Just to remind, using system("pause"); is a bad habit security-wise.

What it really does is it calls for program called pause. What if someone deletes it? What if someone replaces it with their own program, which is being ran because you use system("pause");? Bad. Bad. Bad. Repeat it. Say it! ;)

Besides, it does not work with Linux for example. Might work with few distros. It is heavy as hell aswell.

So, what about using something which is moer secure, "lighter" and OS-independent?

for C++ cin.get(); It halts the program until enter is being pressed.
And alternative for C: getchar();

Polizei
04-18-2008, 05:58 AM
Instead of system("pause"), we use "while (!kbhit())", which is the whole "press any key" thing.

Calmatory
04-24-2008, 09:10 AM
Instead of system("pause"), we use "while (!kbhit())", which is the whole "press any key" thing.
...which doesn't really belong to C/C++ standard.

Sure anyone can use whatever they want to, but I'd personally strongly suggest people to stick with C/C++ standard as much as possible.

CrazyNutz
04-28-2008, 08:45 AM
This is out of scope, but when you get out of school, and start programming
C in the real world don't use these methods to copy data, the real way is
like this:

main()
{
double source[5] = { 1.1, 2.2, 3.3, 4.4, 5.5 };
double target1[5];

memcpy(&target1, &source, sizeof(double) * 5); // 1 line, and it executes way faster!

}

This obviously would not satisfy the assignment, but Im just giving you a pointer on how data (array's, etc..) is normally copied.
The only exception would be if you have to copy data out of order like your first assignment, then you could not use memcpy().

TheSilence
04-29-2008, 09:43 AM
This is out of scope, but when you get out of school, and start programming
C in the real world don't use these methods to copy data, the real way is
like this:

main()
{
double source[5] = { 1.1, 2.2, 3.3, 4.4, 5.5 };
double target1[5];

memcpy(&target1, &source, sizeof(double) * 5); // 1 line, and it executes way faster!

}

This obviously would not satisfy the assignment, but Im just giving you a pointer on how data (array's, etc..) is normally copied.
The only exception would be if you have to copy data out of order like your first assignment, then you could not use memcpy().


I'm pretty sure the professor made them do it manually so that they could learn later how to use something like malloc and memcpy to allocate memory and copy memory. Just giving them a function call doesn't teach them anything.

Polizei - now that everyone's been so kind to write the homework solution for you, I'll tell you that if you want to do well on the upcoming test I'd figure out the difference between these two lines from m0da's code:



target1[i] = source[i]; //Copy using array notation
*(target2 + i) = *(source + i); //Copy using pointer notation


While it does the same thing in a longer way, a better way to understand pointer notation is to use the following implementation of copy_ptr



void copy_ptr(double *source, double *target2, int size)
{
int i = 0;
double *newsrc = source, *newtgt = target2;

printf("Target2 contains: ");
for (i = 0; i < size; i++)
{
*newtgt = *newsrc;
printf("&#37;g ", *newsrc);
newsrc++;
newtgt++;
}
printf("\n");
}


EDIT: Also note that we assume the memory for target2 has already been allocated, but in the real world you'd have to check and make sure otherwise there would be problems.

tobe22
05-20-2008, 10:15 AM
memcpy(&target1, &source, sizeof(double) * 5); // 1 line, and it executes way faster!


Not always true -- for small arrays, it's faster to copy them explicitly; memcpy is faster for larger copies.

Here's a couple ways to do the ptr copy, just to show you there's no right way to do it -- but there are other ways to do it =)



/* posted by m0da */
void copy_ptr(double *source, double *target2, int size)
{
int i = 0;
printf("Target2 contains: ");
for (i = 0; i < size; i++)
{
*(target2 + i) = *(source + i);
printf("&#37;g ", *(target2 + i));
}
printf("\n");
}




#include <stdio.h>

/* uses the ptr copies and a while loop instead
void copy_ptr(double *source, double *target2, int size)
{
/* you should check if size is a negative number */
/* and return, but not necessary if it's just you */
if(size <= 0)
return;

/* "source" and "target2" are copies */
while(size--)
{
*target2++ = *source++;
}
}

int main()
{
int i;
double source[5] = { 1.1, 2.2, 3.3, 4.4, 5.5 };
double target2[5];

double* s0 = source;
double* s1 = target2;

printf("%x, s0 before copy_ptr\n", s0);
printf("%x, s1 before copy_ptr\n", s1);
copy_ptr(s0, s1, 5);
printf("%x, s0 after copy_ptr\n", s0);
printf("%x, s1 after copy_ptr\n", s1);

printf("source:\n");
for(i=0;i<5;++i)
printf("%f,",source[i]);
printf("\n");

printf("target2:\n");
for(i=0;i<5;++i)
printf("%f,",target2[i]);
printf("\n");

getchar();
return(0);
}


TheSilence posted a solution, by making local copies of the double pointers inside copy_ptr, but that's unnecessary, because the pointers that you pass in are already copies; functions that accept copies of variables are called "pass by value". See the s0 and s1 printf's in main() above; this is consequence of "scope".

Now there *is* away to change s0 and s1 inside a function, that's a pointer to a pointer (or done up in C++ as a pointer reference) -- but I won't get into that here.

Pointers are an important concept in C (and even C++), accept and understand them =) but pass by value, and scope play a very important role in C as well (especially when you get into recursion).

Study hard, and never be afraid to ask questions.