LebGeeks

A community for technology geeks in Lebanon.

You are not logged in.

#26 June 18 2010

nuclearcat
Member

Re: C Programming Final Exams

Kassem wrote:
nuclearcat wrote:

1.

int func (int *array,int length) {
    int i;
    for (i=0;i<(length/2);i++) {
       array[i] ^= array[length-1-i];
       array[length-1-i] ^= array[i];
       array[i] ^= array[length-1-i];
    }
}

Code is not portable. There is few other tricky ways possible...

Is there a simpler way?

Yes, but it will not be C (XCHG), and i think my code will lead on optimization to use this instruction or it will introduce temporary variable (but if compiler enough smart - he will optimize it out).
I'm lazy to do, but for x86 you can use also SIMD instructions, i think.

Offline

#27 June 18 2010

Joe
Member

Re: C Programming Final Exams

@Kassem :
The code you posted works ! I copy/pasted, compiled it works. Depending on your compiler, it might not accept you declaring int i inside the loop condition. Try declaring it first.

Also I would declare temp[size] instead of temp[5] (for obvious reasons).

Offline

#28 June 18 2010

Joe
Member

Re: C Programming Final Exams

nuclearcat wrote:

rahmu - ur way will fail if a+b will overflow integer variable.

You are right, I had not thought about it, thank you for pointing that out.
I still think it is a nice 'mathematical' alternative to declaring a third temp variable.

Offline

#29 June 18 2010

Kassem
Member

Re: C Programming Final Exams

I am using Visual Studio 2010. I tried what you said about using temp[size] but it gave me the following error:

Error    1    error C2057: expected constant expression

And declaring int i outside the loop doesn't change anything...

Offline

#30 June 18 2010

Kassem
Member

Re: C Programming Final Exams

Here's one of my attempts at solving the second exercise - which failed miserably btw lol.

#include <stdio.h>

void swap(int *arr1, int *arr2);
void printOut(int *);	
void fillArray(int *);

void main() {
	int a1[5][5];
	int a2[5][5];

	printf("Please fill in the first array\n");
	fillArray(a1[0][0]);

	printf("Please fill in the second array\n");
	fillArray(a2[0][0]);

	swap(a1[0][0], a2[0][0]);
	printOut(a1[0]0]);
	printOut(a2[0][0]);
}

void fillArray(int *arr)
{
    for(int i = 0; i < 5; i++)
    {
        for(int j = 0; j < 5; j++)
        {
            printf("Please enter the value of Array[",i,"][",j,"]:\n");
            scanf("%d", arr[i][j]);
        }
    }
}

void swap(int *a1, int *a2)
{
    int temp;
    for(int i = 0; i < 5; i++)
    {
        for(int j = 0; j < 5; j++)
        {
            if((i == j)||(5-i == 5-j))
            {
                temp = a1[i][j];
                a1[i][j] = a2[i][j];
                a2[i][j] = temp;
            }
        }
    }
}

void printOut(int *arr[5][5])
{
    for(int i = 0; i < 5; i++)
    {
        for(int j = 0; j < 5; j++)
        {
            printf("%d\t", arr[i][j]);
        }
        printf("\n");
    }
}

What error(s) can you find in my code?

P.S: My prof. didn't have enough time to explain the use of pointers to us. I'm still trying to find my way around them... A little help on the issue would be greatly appreciated. Thanks.

Offline

#31 June 18 2010

nuclearcat
Member

Re: C Programming Final Exams

rahmu wrote:
nuclearcat wrote:

rahmu - ur way will fail if a+b will overflow integer variable.

You are right, I had not thought about it, thank you for pointing that out.
I still think it is a nice 'mathematical' alternative to declaring a third temp variable.

use int64_t for intermediate value and maybe some casting... it will be non-trivial, but more proper(portable) than XOR. But it will be racy for threaded programs.

Offline

#32 June 18 2010

nuclearcat
Member

Re: C Programming Final Exams

Kassem wrote:

Here's one of my attempts at solving the second exercise - which failed miserably btw lol.

Try to abandon Visual Studio. Studio users becoming idiots, sorry to say.
gcc didn't compile your code, and declaring ...for (int i = 0;... is violation of C99 standard.

As tricks, you can for example use instead of i and j, just i. Look here :-)

void main() {
    int i;
    
    for (i=0; i < 5*5; i++) {
//      printf("Enter element x:%d y:%d\n",(i/5)+1,(i%5)+1); // start from 1 :-)
        printf("Enter element x:%d y:%d\n",(i/5)+1,(i%5)+1);
// sscanf here?
    }

}

I will give you small snippet of code i wrote now, maybe will help you understand how pointers works. If u can't - let me know, i will explain here then.

#include <stdio.h>
#include <string.h>

void printOut(void *arr) {
    int *i = arr;
    printf("Element %d\n",*(i+7));
}


int main() {
    int i[5][5];

    memset(&i,0x0,5*5*sizeof(int));
    
    i[1][2] = 123;

    printOut(&i);
    return(0);
}

Offline

#33 June 18 2010

arithma
Member

Re: C Programming Final Exams

@nuclearcat: If you don't like VS, we don't have to dislike it.. Leave this up to personal preference. Compatibility issues will only matter when the person doing the programming will care (it doesn't when the person doing the programming doesn't care, as in when learning generally how to program)
---
xor operation is a basic logic operation. I believe it is as portable as it can get (no platform specifics).
As for rahmu's method, buffer overflows don't affect its correctness one bit - when applied using unsigned addition and subtraction.

C++ code exhibit.
It gets fucked up if you use signed chars. I am sure you can do some type casting specific for the swapping.

#include <iostream>
using namespace std;

void main(){
	unsigned char a = 230;
	unisgned char b = 50;

	a = a + b;
	b = a - b;
	a = a - b;

	cout << (unsigned int)a << ", " << (unsigned int)b << endl;
}

I liked rahmu's method as it is mathematically based. However, there's a larger pattern here. Any operation can be used as long as it is reversible (given one of the arguments).

Specifically:
[a, b]
[f(a,b), b]
[f(a,b), g(f(a,b), b)] = [f(a,b), a]
[g(f(a,b), a), a] = [b, a]

Thinking about it, g and f have to be linear functions on the domain they're applied to (which can be thought of in a modular way, so that the domain wraps around itself). That means that subtraction and addition is the only solution. Incidentally, exclusive or is both subtraction and addition when it comes down to a single bit.

Last edited by arithma (June 18 2010)

Offline

#34 June 18 2010

nuclearcat
Member

Re: C Programming Final Exams

arithma wrote:

@nuclearcat: If you don't like VS, we don't have to dislike it.. Leave this up to personal preference. Compatibility issues will only matter when the person doing the programming will care (it doesn't when the person doing the programming doesn't care, as in when learning generally how to program)

Learn how to program properly. Changing yourself later and realising that your code is crap and non-portable - painful. Especially if you will write this code on interview for first job.

It is not a big matter to declare variables at the beginning of function, and except it is right C99, it is also improving readability of the code,

xor operation is a basic logic operation. I believe it is as portable as it can get (no platform specifics).
As for rahmu's method, buffer overflows don't affect its correctness one bit - when applied using unsigned addition and subtraction.

C standard says that when a value of an operand is changed in the same expression at some other place, then the result of the expression is undefined. This is why not portable.

What about negative values? Overflow is overflow, and it can happen. And if you use this code in real world program, you must be pretty sure this algo will not overflow. Since C doesn't have portable integer overflow exceptions - it will be difficult to find a bug in such code.

Another way, you can just keep array as array of pointers, and just exchange pointers. Because pointers is linear, you don't need swap values, just make array1[element] = array2[element], then array2[element] = array1[element]+sizeof(int); (previous pointer in array where is ptr1, since they are linear you can restore ptr1 value). Lazy to code it, but if someone wants too much - will do that. But at any case it is fragile and not useful except as proof of concept.

Offline

#35 June 18 2010

arithma
Member

Re: C Programming Final Exams

Learn how to program properly. Changing yourself later and realising that your code is crap and non-portable - painful. Especially if you will write this code on interview for first job.

If I had to choose a trainee who knew how to program and think in comparison to one who knew standards and was anal about it I'd be happy to pick the one who knew how to think.

As for the negative values: casting into unsigned values, doing the swap under the assumption of unsigned values (even if the bits represented negative numbers) will yield correct results. (Swapping bits is swapping bits). The trick is subtraction and addition under a closed warping (modula domain) still has the reverse property (addition is f and subtraction is g from the previous post).

Offline

#36 June 18 2010

arithma
Member

Re: C Programming Final Exams

C standard says that when a value of an operand is changed in the same expression at some other place, then the result of the expression is undefined. This is why not portable.

This means that statements like:
i = i++ + --i;
are undefined. I don't see how it applies to the code you posted. You didn't write any expression that changed any value twice.

Offline

#37 June 19 2010

Kassem
Member

Re: C Programming Final Exams

@nuclearcat: I think you're assuming I'm a C language guru or something. I cannot understand any of you code. and I do not know what the xor operator is. My knowledge about C doesn't go beyond what I've taken in class so far, and that's not much at all. I was the only one to score 30/30 on my partial exam but that doesn't make me any good in C. I hope you understand that, so please keep your code simple :)

I still do not understand how you could fill or read a two dimensional array using one loop! And what's the meaning of "overflow"? lol I feel like I'm such a noob in this thread :)

Anyway, if someone would provide me with the solutions to the first two exercises I posted that would be greatly appreciated. I will not worry about strings for now since they're not required. And please, do not use any "tricks" in your code, just keep it simple. I will not worry about code optimization and standards for now, I just want to get a very good grade on my exam (55+/60).

P.S: Anyone knows a good tutorial that explains pointers?
EDIT: Ok found one here it is if anyone needs it.

Thanks in advance.

Last edited by Kassem (June 19 2010)

Offline

#38 June 19 2010

Padre
Member

Re: C Programming Final Exams

ok, this is written without any tricks

#include <stdio.h>

#define ARY_SIZE 5

void swap_diag( int [][ARY_SIZE], int [][ARY_SIZE]);
void print_ary(int [][ARY_SIZE]);


int main()
{
	int A[ARY_SIZE][ARY_SIZE];
	int B[ARY_SIZE][ARY_SIZE];

	int i;
	int j;
	for (i=0;i<ARY_SIZE;i++)
	{
		for (j=0;j<ARY_SIZE;j++)
		{
			A[i][j]=i+j+10;
			B[i][j]=i*j*j;
		}
	}
	printf("Arry A: \n");
	print_ary(A);
	printf("Arry B: \n");
	print_ary(B);
	swap_diag(A,B);

	printf("Arry A: \n");
	print_ary(A);
	printf("Arry B: \n");
	print_ary(B;);

}

void print_ary(int A[][ARY_SIZE])
{
	int i;
	int j;
	for (i=0;i<ARY_SIZE;i++)
	{
		for (j=0;j<ARY_SIZE;j++)
			printf("%i \t",A[i][j]);
		 printf("\n");
	}
}

void swap_diag(int A[][ARY_SIZE], int B[][ARY_SIZE])
{
	int i;
	int temp;

	for (i=0;i<ARY_SIZE;i++)
	{
		temp = A[i][i];
		A[i][i]=B[i][i];
		B[i][i]=temp;
	}
}

Offline

#39 June 19 2010

Kassem
Member

Re: C Programming Final Exams

@ Padre: lol yeh your code is very clear and readable. But I have some questions though...
1. What is '%i' used for? I only know '%d', '%f', '%p', '%c'... at least those are the ones I've taken so far :)
2. That's how a two dimensional array is passed as an argument of a function? I do not need pointers or anything in the prototype and definition of the function?
3. in the swap_diag() function, I think you're swapping the whole array and not just the diagonals, right?

Offline

#40 June 19 2010

Padre
Member

Re: C Programming Final Exams

1- Integer
2- There are numerous ways to pass arrays to a function, this is one of them
3-Nop, only diagonal. a single loop from 1 till size, and im always taking item 1,1 - 2,2 - 3,3 -> diagonal.

Offline

#41 June 19 2010

rolf
Member

Re: C Programming Final Exams

arithma wrote:

If I had to choose a trainee who knew how to program and think in comparison to one who knew standards and was anal about it I'd be happy to pick the one who knew how to think.

Anal is hot!

Offline

#42 June 19 2010

Kassem
Member

Re: C Programming Final Exams

Padre wrote:

1- Integer
2- There are numerous ways to pass arrays to a function, this is one of them
3-Nop, only diagonal. a single loop from 1 till size, and im always taking item 1,1 - 2,2 - 3,3 -> diagonal.

1. oh I see... I thought '%d' is for integer...
2. Mind mentioning some of the others?
3. Oh yeah you're right... But you're missing the other diagonal though... and that can be considered using A[ARY_SIZE - i][ARY_SIZE - i]

Anyway, thanks for the help man. Appreciated :)

Offline

#43 June 19 2010

rolf
Member

Re: C Programming Final Exams

nuclearcat wrote:

1.

int func (int *array,int length) {
    int i;
    for (i=0;i<(length/2);i++) {
       array[i] ^= array[length-1-i];
       array[length-1-i] ^= array[i];
       array[i] ^= array[length-1-i];
    }
}

Code is not portable. There is few other tricky ways possible...

That's some crazy code you got there!
Why not just create a new array and fill it backwards?
I know, your code is probably faster, but what difference does it make in this case?
In any case?? Unless you're programming critical kernel functions, in most cases it wont matter.

Offline

#44 June 19 2010

arithma
Member

Re: C Programming Final Exams

rolf wrote:
arithma wrote:

If I had to choose a trainee who knew how to program and think in comparison to one who knew standards and was anal about it I'd be happy to pick the one who knew how to think.

Anal is hot!

Maybe skirt anal. Even then..

Kassem, you still need anything?

Last edited by arithma (June 19 2010)

Offline

#45 June 19 2010

Kassem
Member

Re: C Programming Final Exams

arithma wrote:

Kassem, you still need anything?

I just need to understand how to pass an array as an argument of a function. My prof. said the function should be expecting a pointer, but Padre's code doesn't show that...

Offline

#46 June 19 2010

arithma
Member

Re: C Programming Final Exams

void print_ary(int* A, int rows, int columns)
{
    int i;
    int j;
    for (i=0;i<rows;i++)
    {
        for (j=0;j<columns;j++)
            printf("%i \t",A[i*rows+j]);
         printf("\n");
    }
}

This code will allow you to access 2D arrays of arbitrary width and height. The thing to note is that internally, A[1][0] comes right after A[0][columns-1], that's why we can use index multiplication.

You'd pass in print_ary(&A[0][0], ARY_SIZE, ARY_SIZE)..

Enjoy :)

Offline

#47 June 19 2010

Padre
Member

Re: C Programming Final Exams

or if you want to keep the A[X][Y] u can use

 print_ary(int **A, int rows, int columns)

if i remember correctly

Offline

#48 June 19 2010

rolf
Member

Re: C Programming Final Exams

@nuclearcat, you have a problem in your code,
I think the 3rd line:

       array[i] ^= array[length-1-i];

Is a mistake, and it's the same then the 1st one.

It's f*** crazy though, bitwise XOR can actually reverse the array :)
I did it with a paper and a pen, and it works! Took me 1/2 hour to understand.

Last edited by rolf (June 19 2010)

Offline

#49 June 19 2010

arithma
Member

Re: C Programming Final Exams

Padre wrote:

or if you want to keep the A[X][Y] u can use

 print_ary(int **A, int rows, int columns)

if i remember correctly

You can't since it has no way to know what size the dimension is (int ** can mean any dimension). What you probably meant was:
int (*A)[ARY_SIZE] is the closest thing you'll get.
You can use the A[i][j] with this declaration, and to pass arguments in as well.

Offline

#50 June 19 2010

arithma
Member

Re: C Programming Final Exams

You guys should take the program apart, and implement swap apart from the array reversal to make things clear.

Offline

Board footer