Related
I'm bad at C pointers, I'm not sure how should I sort the whole array, the code below sorted the array row-wise only, with a warning "assignment discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]". This code sure works in Windows, not sure for other OSes. I am supposed to create a function called snake with 2D const int pointer array, and its size, m as inputs. I am not allowed to move or swap the contents within the array to be scanned, also the whole main function is not allowed to be edited. For example, the input for the whole program is
3
9 8 7
5 4 6
3 2 1
The correct output should be
1 2 3
6 5 4
7 8 9
Instead, I got this
7 8 9
4 5 6
1 2 3
And here is my code. There is a commented section in snake() because the assert function will fail if I uncomment it. I was trying to reverse the even rows (but the index starts from 0, so you can say odd rows also) after sorting.
#include <stdio.h>
#include <assert.h>
void snake(const int *ptr_array[100][100], int m){
int* p =NULL;
int temp;
for(int y=0;y<m;y++){
for(int k=0;k<m-1;k++){
for(int g=0;g<m-k-1;g++){
if(*ptr_array[y][g]>*ptr_array[y][g+1]){
p=(ptr_array[y][g]);
(ptr_array[y][g])=(ptr_array[y][g+1]);
(ptr_array[y][g+1]) = p;
}
}
}
}
// for(int h=1;h<m;h+=2){
// for(int g=0;g<m/2;g++){
// p = (ptr_array[h][m-g]);
// (ptr_array[h][m-g]) = (ptr_array[h][g]);
// (ptr_array[h][g]) = p;
// }
// }
}
int main()
{
int array[100][100], check[100][100];
const int *ptr_array[100][100];
int i, j, m;
scanf("%d", &m);
for (i = 0; i < m; i++){
for (j = 0; j < m; j++) {
ptr_array[i][j] = &(array[i][j]);
scanf("%d", &(array[i][j]));
check[i][j] = array[i][j];
}
}
snake(ptr_array, m);
for (i = 0; i < m; i++) {
for (j = 0; j < m; j++) {
assert(check[i][j] == array[i][j]);
assert((ptr_array[i][j] >= &array[0][0]) && (ptr_array[i][j] <= &array[99][99]));
printf("%d ", *(ptr_array[i][j]));
}
printf("\n");
}
return 0;
}
#include <stdio.h>
void snake(const int *ptr_array[100][100], int m){
int* p =NULL;
int* w=NULL;
int temp,l;
for(int y=0;y<m;y++){
for(int k=0;k<m;k++){
p = ptr_array[y][k];
l = k+1;
for(int g=y;g<m;g++){
while(l<m){
if(*p>*ptr_array[g][l]){
p=(ptr_array[g][l]);
(ptr_array[g][l])=(ptr_array[y][k]);
(ptr_array[y][k]) = p;
}
l++;
}
l=0;
}
}
}
for(int h=1;h<m;h+=2){
for(int g=0;g<=(m-1)/2;g++){
w = (ptr_array[h][m-1-g]);
(ptr_array[h][m-1-g]) = (ptr_array[h][g]);
(ptr_array[h][g]) = w;
}
}
}
I'm writing a C for which I need to create a 2D array. I've found a solution to my problem using double pointers (pointers to pointers) in the following way:
#include <stdio.h>
#include <stdlib.h>
int d = 3;
#define DIM_MAX 9
void changeArray(int d, int *array[d]);
int main()
{
//alocate array of 'd' colummns and 'd' row using malloc using array of pointers
int **array = malloc(d*sizeof(int *));
for(int count = 0; count < d; count++)
{
array[count] = malloc(d*sizeof(int *));
}
/* Call changeArray function */
changeArray(d, array);
for(int i = 0; i < d; i++)
{
for(int j = 0; j < d; j++)
{
printf("%d ", array[i][j]);
}
printf("\n");
}
for(int count = 0; count < d; count++)
{
free(array[count]);
}
return 0;
}
void changeArray(int n, int *array[d])
{
for(int i =0; i < n; i++)
{
for(int j = 0; j < n; j++)
{
array[i][j] = i*j;
}
}
return;
}
The code above works pretty well (it seems), but I've read in the web that using pointer to pointer is not the correct way to create 2D arrays. So I've come up with the following code, which also works:
#include <stdio.h>
#include <stdlib.h>
#define DIM_MAX 9
int d = 3;
void changeArray(int d, int *array[d]);
int main()
{
//alocate array of 'd' colummns and 'd' row using malloc using array of pointers
int *array[DIM_MAX] = {0};
for(int count = 0; count < d; count++)
{
array[count] = (int *)malloc(d*sizeof(int *));
}
/* Call changeArray function */
changeArray(d, array);
for(int i = 0; i < d; i++)
{
for(int j = 0; j < d; j++)
{
printf("%d ", array[i][j]);
}
printf("\n");
}
for(int count = 0; count < d; count++)
{
free(array[count]);
}
return 0;
}
void changeArray(int n, int *array[d])
{
for(int i =0; i < n; i++)
{
for(int j = 0; j < n; j++)
{
array[i][j] = i*j;
}
}
return;
}
What is the difference in using any of the two ways above to write this code?
[Not an answer, but an alternative approach to achieve the desired result, namely defining a user-defined 2D array.]
Assuming the compiler in use supports VLAs you could do this:
#include <stddef.h> /* for size_t */
void init_a(size_t x, size_t y, int a[x][y]); /* Order matters here!
1st give the dimensions, then the array. */
{
for (size_t i = 0; i < x; ++i)
{
for (size_t j = 0; j < y; ++j)
{
a[i][j] = (int) (i * j); /* or whatever values you need ... */
}
}
}
int main(void)
{
size_t x, y;
/* Read in x and y from where ever ... */
{
int a[x][y]; /* Define array of user specified size. */
init_a(x, y, a); /* "Initialise" the array's elements. */
...
}
}
It is actually pretty simple. All you have to do is this:
int i[][];
You are overthinking it. Same as a normal array, but has two indexes.
Let's say you want to create a "table" of 4 x 4. You will need to malloc space for 4 pointers, first. Each of those index points will contain a pointer which references the location in memory where your [sub] array begins (in this case, let's say the first pointer points to the location in memory where your first of four arrays is). Now this array needs to be malloc for 4 "spaces" (in this case, let's assume of type INT). (so array[0] = the first array) If you wanted to set the values 1, 2, 3, 4 within that array, you'd be specifying array[0][0], array[0][1], array[0][2], array[0][3]. This would then be repeated for the other 3 arrays that create this table.
Hope this helps!
I want to make a function that removes elements from an array.
I attempted making the function myself, however, not fully successful:
void remove_element(int* array, int number, int array_length)
{
int i, j;
for (i = 0; i < array_length; i++){
if (array[i] == number) {
for (j = i; j < array_length; j++)
array[j] = array[j+1];
array_length--;
}
}
}
first thing I noticed is after function is called in main, array_lenght is not changed, therefore length of an array remains the same after removing element(s).
So the first question is how to change length of an array inside the void function?
Second thing which doesn't work properly is if in an array are two or more same numbers next to each other, for example if array contains 1,1,3,4,5,6 and user wants to remove 1 function will remove only one element.
Example of my output (wrong):
1,1,3,4,5,6 after fucntion 1,3,4,5,6
Thanks
In the current signature you cannot modify the array, as returning the new array you also need to return the new length.
There are many ways to do it, here is a way with a single loop:
void
remove_element(int* array, int number, int *array_length)
{
int i, j;
for (i = 0, j=0; i < *array_length; i++) {
if (array[i] != number)
array[j++] = array[i];
}
*array_length = j;
}
Doing so, this will mutate both the initial array and the variable keeping its length in the caller and you must pass the value of array_length by reference, somthing like
int* some_array, some_array_length, n;
remove_element(some_array, n, &some_array_length)
Other method would be to return the new length and mutate the array or allocate a new array in the heap and return both the allocated array and the new length.
The other answers to your question aside, if you're likely to do more than one removal on average (or more than one per call ever, actually), it's better not to shift all the subsequent values again and again. Try this:
void remove_element(int *array, int number, int *array_length) {
for(int iRead = 0, iWrite = 0; iRead < *array_length; iRead++) {
if(array[iRead] == number)
continue; /* skip without increasing iWrite */
if(iWrite < iRead) /* it works without this line, too, what's better depends */
array[iWrite] = array[iRead];
iWrite++;
}
*array_length = iWrite;
}
How this works, e.g., with array = {1,1,2,2,3} and number = 2:
1 1 2 2 3
^ iRead
^ iWrite
(increases both, writes nothing)
1 1 2 2 3
^ iRead
^ iWrite
(increases both, writes nothing)
1 1 2 2 3
^ iRead
^ iWrite
(continue happens: increases only iRead)
1 1 2 2 3
^ iRead
^ iWrite
(continue happens: increases only iRead)
1 1 2 2 3
^ iRead
^ iWrite
(writes 3 to iWrite, increases both)
1 1 3 2 3
^ iRead = 5
^ iWrite = 3
(iRead is no longer < *array_length, loop stops, 3 == iWrite is the new length)
Based now on your Comments, I'll do it like this:
#include <stdio.h>
void remove_element(int number, int *arr, size_t *size);
int main(void){
int arr[] = {1,1,3,4,5,6};
long unsigned int arrSize;
int number = 1;
arrSize = sizeof arr / sizeof arr[0];
printf("Before:\n");
for ( size_t i = 0 ; i < arrSize ; i++ ){
printf("%d ", arr[i]);
}
printf("\nAfter:\n");
remove_element( number, arr, &arrSize );
for ( size_t j = 0 ; j < arrSize ; j++ ){
printf("%d ", arr[j]);
}
printf("\n");
}
void remove_element(int number, int *arr, size_t *size){
int arrTemp[*size];
long unsigned int j = 0,c;
for ( size_t i = 0 ; i < *size ; i++ ){
if ( arr[i] == number ){
continue;
}else{
arrTemp[j] = arr[i];
j++;
}
}
for ( size_t k = 0 ; k < j ; k++ ){
arr[k] = arrTemp[k];
}
c = j;
while ( *size > c ){
arr[c] = 0;
c++;
}
*size = j;
}
Output:
Before:
1 1 3 4 5 6
After:
3 4 5 6
By the way in your Question you said:
Examples of output:
1,1,3,4,5,6 after fucntion 1,3,4,5,6
And in your Comment you said:
It doesn't matter how many same numbers there are, in that case above if user wants to remove 1, all 1 's should be removed.
Please make up your mind.
Because array_length is not passed as pointer you're having copy of it on stack, so after you're getting outside of this function you're still having old value. You could use here memmove or memcpy instead of iteration over whole array after you find the same number. The reason why you didn't delete the next 1 in your array is, because when you're on i = 0 -> array[0] == 1, but when you move all of the numbers back then you move second 1 to array[0], without checking it afterwards because after you finished iteration you just increment i, without checking if what you moved to current value of array[i] is the same as previous one.
void remove_element(int *array, int number, int *array_length){
int sameValues = 0;
for(int i = 0; i < *array_length; i++){
while(array[i] == number){
*array_length--;
sameValues++;
}
if(sameValues > 0){
if(i < *array_length){
memmove(&array[i], &array[i + sameValues], (*array_length - i) * sizeof(int));
}
sameValues = 0;
}
}
}
To make it even more dynamic you could use realloc (and actually resize the space occupied by your array after you remove members, but then either you need to return new pointer or you need to point to pointer on your stack from where you call the function:
void remove_element(int **array, int number, int *array_length){
int sameValues = 0;
for(int i = 0; i < *array_length; i++){
while((*array)[i] == number){
*array_length--;
sameValues++;
}
if(sameValues > 0){
if(i < *array_length){
memmove(&(*array)[i], &(*array)[i + sameValues], (*array_length - i) * sizeof(int));
}
realloc(*array, *array_length);
sameValues = 0;
}
}
}
P.S. To use memmove you need to include string.h
When you declare an array the compiler will affect an amount of memory, and with array structure you can't change it. There is 2 solutions, change your array length but you still could access to the last "box" or redefine an array with the size wanted.
1st case :
void remove_element(int* array, int number, int * array_length){
int i = 0,j = 0;
while( i < *(array_length)-1){
if(array[i] == number && !find){
i++; //we step over
find = 1; //we find 1 element stop remove
}
array[j] = array[i];
i++;
j++;
}
*(array_length)--;
}
The int * array_length is a pointer to the memory, so your changes are keep when you go back in main. In your example, before remove_element array_length is equal to 6, and after it's 5. But you still could do array[5] (6th element cause notation 0 to 5 in c).
2nd case
int * remove_element(int * array, int number, int * array_length){
int * new_array = malloc((array_length -1) * sizeof(int)); // len - 1 cause we want to delet only 1 element
int i = 0;
int j = i;
int find = 0;
while( i < *(array_length)-1){
if(array[i] == number && !find){
i++; //we step over
find = 1; //we find 1 element stop remove
}
new_array[j] = array[i];
i++;
j++;
}
if (array[array_length] != number && !find){ //if we didn't find att all the element return array
return array;
} else {
*(array_length)--;
return new_array;
}
}
Here you have to return the new_array because int array[6] in your main is a constant : you can't change it with array = new_array.
Edit : yes of course when you don't need anymore your array you have to free it with free(array) (or it's automatically done at the end of the processus, but it's not proper code)
There is also a shorter method with addtion of pointers but it seems quite too complicated with your c lvl :)
Part of my assignment is to sort a 2D array into ascending order, and I cannot figure out how to do it for the life of me.
What I have so far:
int Sort2DArray(int A[][COL], unsigned int rowsize, unsigned int colsize)
{
int i, j, k, temp;
for (i=0; i<rowsize-1; i++){
for (k=0; k<colsize; k++){
for (j=0; j<rowsize-1; j++){
do {
temp = A[k][j];
A[k][j] = A[k][j+1];
A[k][j+1] = temp;
} while (A[k][j]>A[k][j+1]);
}
}
}
}
This will take an array this and return:
3 2 1 1 2 3
5 8 7 ---->>> 5 7 8
4 9 3 3 4 9
However, I need it to return:
1 2 3
4 5 6
7 8 9
So, is there any way you guys can help me? Thanks!
EDIT:
#include <stdio.h>
#include <stdlib.h>
#define COL 20
#define ROW 20
void PopulateArray2DUnique (int [][COL], unsigned int, unsigned int, int, int);
void DisplayArray2D(int [][COL], unsigned int, unsigned int);
int FindLargest(int [][COL], unsigned int, unsigned int);
int FindColSum(int [][COL], unsigned int, unsigned int, unsigned int);
int Sort2DArray(int [][COL], unsigned int, unsigned int);
int main()
{
int A[ROW][COL];
int min=1, max=99;
unsigned int rowsize, colsize, col_to_sum;
printf ("Input your desired row and column size: \n");
scanf ("%u%u", &colsize, &rowsize);
PopulateArray2DUnique(A, rowsize, colsize, min, max);
DisplayArray2D(A, rowsize, colsize);
FindLargest(A, rowsize, colsize);
printf ("Which column would you like to find sum of?\n");
scanf ("%d", &col_to_sum);
FindColSum(A, rowsize, colsize, col_to_sum);
Sort2DArray(A, rowsize, colsize);
DisplayArray2D(A, rowsize, colsize);
return 0;
}
Is it possible?
Yes, it's possible. The most important thing to understand is that your sort routine, and all of the basic sort routines you see in examples, generally sort a 1D array.[1] The same routine can be used to sequentially sort a 2D array as you are attempting to do, but you have to recognize you want to pass your 2D array to the sort function as a pointer-to-type (simple 1D array, e.g. 'int *'), rather than as a pointer-to-array of X elements (your 2D array, e.g. 'int (*)[NCOLS]')
The key to passing the array is to simply pass the address to the first element in your array. Regardless of whether you declared it as a 1D or 2D array (1) that is the address where the values begin in memory; and (2) all array values are sequential. Meaning that you can address every value in a 1D or 2D array by start_address + offset.
Take for example your simple bubble-sort routine:
void bubblesort (int *a, size_t n)
{
size_t i, j;
int temp;
for (i = 0; i < n; i++) {
for (j = 0; j < (n-1); j++) {
if (a[j] > a[j + 1]) {
temp = a[j + 1];
a[j + 1] = a[j];
a[j] = temp;
}
}
}
}
If you had declared a 2D array (e.g. int array[][NCOL];, not pointer-to-pointer-to-type int **array;) that you wished to sequentially sort, you could call your sort routine by simply passing the start address as follows:
bubblesort (*array, nelem);
or
bubblesort (&array[0][0], nelem);
(both are equivalent, with 'nelem' being the total number of elements)
If you attempt to declare your sort function by passing a pointer to array (e.g. bubblesort (int (*array)[NCOL], size_t n); you will run difficulty immediately attempting to loop over the indexes because using the traditional nested loop layout, there is no easy way to compare array[i][j] with array[i+1][0], etc..
The following is a short example putting it all together. Look it over and let me know if you have questions:
#include <stdio.h>
#include <stdlib.h>
#define NCOL 3
void bubblesort (int *a, size_t n);
int main ()
{
int array[][NCOL] = {{3,2,1},
{5,8,7},
{4,9,3}};
int i, j, nrows, nelem;
nrows = sizeof array/sizeof *array;
nelem = sizeof array/sizeof **array;
printf ("\noriginal:\n\n");
for (i = 0; i < nrows; i++) {
for (j = 0; j < NCOL; j++)
printf (" %2d", array[i][j]);
putchar ('\n');
}
bubblesort (*array, nelem);
printf ("\nsorted:\n\n");
for (i = 0; i < nrows; i++) {
for (j = 0; j < NCOL; j++)
printf (" %2d", array[i][j]);
putchar ('\n');
}
return 0;
}
void bubblesort (int *a, size_t n)
{
size_t i, j;
int temp;
for (i = 0; i < n; i++) {
for (j = 0; j < (n-1); j++) {
if (a[j] > a[j + 1]) {
temp = a[j + 1];
a[j + 1] = a[j];
a[j] = temp;
}
}
}
}
Output
$ ./bin/qsort_2d_linear
original:
3 2 1
5 8 7
4 9 3
sorted:
1 2 3
3 4 5
7 8 9
Note: you can do the same thing with qsort rather easily with the standard integer compare function and calling qsort (array, nelem, sizeof **array, icompare);
footnote[1]: all arrays in C are 1D arrays, the 2D array is simply addressed in a way to allow 2D indexing. It is still a sequential block of 'type' values in memory.)
I'm not sure if I have the best method here, however what I would do, is store each value from the array into one large 1D array, sort that and then assign them to the 2D array.
int Sort2DArray(int A[][COL], unsigned int rowsize, unsigned int colsize)
{
int arraySize = rowsize * colsize;
int sortingArray[arraySize];
int i = 0, row, col, temp, prevPos;
//Fills the sortingArray with all the values in the 2D array
for (col = 0; col < colsize; ++col) {
for (row = 0; row < rowsize; ++row) {
sortingArray[i] = A[row][col];
++i;
}
}
//Sorts the 1D array (Insertion Sort)
for (i = 1; i < arraySize; ++i)
{
temp = sortingArray[i];
prevPos = i - 1;
while (j >= 0 && sortingArray[prevPos] > temp)
{
sortingArray[prevPos+1] = sortingArray[prevPos];
prevPos = prevPos - 1;
}
sortingArray[prevPos + 1] = temp;
}
//Writes data back into 2D array
i = 0;
for (row = 0; row < rowsize; ++row) {
for (col = 0; col < colsize; ++col) {
A[row][col] = sortingArray[i];
++i;
}
}
}
I hope I didn't get too confusing with all those dimensions, but you get the idea. If you spot anything incorrect, let me know.
It smells like homework to me, thus, I will only help you a little, and leave the rest to yourself.
When I was very new to C, and my first programming language, I had solved a lot of problems, and one of them was this.
The code I am pasting here is taken from here, a website, which I used to use a lot.
It is up to you to understand the algorithm, and program, and use it in your program.
#include<stdio.h>
int main( )
{
int a[][6]={
{25,64,96,32,78,27}, //Desired solution : {25,27,32,64,78,96},
{50,12,69,78,32,92} // {50,92,78,12,32,69}
};
int i, j, k, temp, temp1 ;
//Bubble sorting is applieed on one first row while the other row is swapped
for(j=1;j<6;j++)
{
for(i=0; i<5; i++)
{
if(a[0][i]>a[0][i+1])
{
temp=a[0][i];
a[0][i]=a[0][i+1];
a[0][i+1]=temp;
temp1 = a[1][i];
a[1][i] = a[1][i+1];
a[1][i+1]=temp1;
}
}
}
printf ( "\n\nArray after sorting:\n") ;
for ( i = 0 ; i <2; i++ )
{
for(j=0; j<6; j++)
{
printf ( "%d\t", a[i][j] ) ; //printing sorted array
}
printf("\n");
}
}
It is a bit different from the code on the site, as I used to always used to work in Ubuntu, and linux never had conio.h. Also, if you are angry for me only providing the code used everywhere, and not doing all your work, keep in mind that homework assignments are for making the student think, and if I spoon-feed you, the purpose will be lost.
NOTE: Always post your full code which can be compiled successfully, as the code you have posted does not compile, as you have not declared all your functions. Thus, it is very difficult to understand you code.
Also, do not try to fool us, as the input you have mentioned does not have a 6, and you want a 6 also to be returned so actually even you have not compiled your code.
How would I get rid of these syntax errors that are not allowing me to compile?
This has the correct structure for what is doing but these errors are preventing me from testing it out.
I am so close to testing this. I did int array and int pointer to fix some of these errors but doing them in the lines with the next errors does not fix them.
It's all the same type of error.
Pointers.c: In function ‘ArrayInitialize’:
Pointers.c:19: error: expected ‘;’ before ‘)’ token
Pointers.c:23: error: expected ‘;’ before ‘)’ token
Pointers.c:25: warning: assignment makes integer from pointer without a cast
Pointers.c: At top level:
Pointers.c:32: error: expected ‘)’ before ‘array’
Pointers.c:44: error: expected ‘)’ before ‘array’
Pointers.c:56: error: expected ‘)’ before ‘array’
Pointers.c:78: error: expected ‘)’ before ‘pointer’
#include <stdio.h>
#include <stdlib.h>
#define SIZE_OF_ARRAY 5
//=============================================================================
int *IntegerPtr;
int ArrayInt[SIZE_OF_ARRAY];
int *ArrayPtr[SIZE_OF_ARRAY];
//-----------------------------------------------------------------------------
void ArrayInitialize(int *array,int *pointer){
int i;
srand(getpid());
for (i =0, i < SIZE_OF_ARRAY; i++;){
array[i] = (int)rand();
for (i =0, i < SIZE_OF_ARRAY; i++;){
pointer[i] = &array[i];
}
}
}
//-----------------------------------------------------------------------------
void ArrayPrint(ArrayInt array){
int i;
for (i =0, int < SIZE_OF_ARRAY; i++;){
printf("%d : %10d \n",i,array[i]);
}
printf("\n");
}
//-----------------------------------------------------------------------------
void ArrayPointerPrint(ArrayInt array){
int i;
for (i =0, i < SIZE_OF_ARRAY; i++){
printf("%d : %10d \n",i,pointer[i]);
}
printf("\n");
}
//-----------------------------------------------------------------------------
void ArrayBubbleSort(ArrayInt array){
int i;
int j;
int temp;
for( i = (SIZE_OF_ARRAY - 1); i >= 0; i-- )
{
for( j = 1; j <= i; j++ )
{
if( *(array+(j-1)) > *(array+j))
{
temp = *array+(j-1));
*array+(j-1)) = array+(j));
*array+(j) = temp;
}
}
}
}
//-----------------------------------------------------------------------------
void PointerBubbleSort(ArrayPtr pointer){
int i;
int j;
int temp;
for( i = (SIZE_OF_ARRAY - 1); i >= 0; i-- )
{
for( j = 1; j <= i; j++ )
{
if( *(pointer+(j-1)) > *(pointer+j))
{
temp = *pointer+(j-1));
*pointer+(j-1)) = pointer+(j));
*pointer+(j) = temp;
}
}
}
}
//-----------------------------------------------------------------------------
int main(void) {
int array[SIZE_OF_ARRAY];
int pointer[SIZE_OF_ARRAY];
ArrayInitialize(array,pointer);
ArrayPrint(array);
PointerBubbleSort(pointer);
ArrayPointerPrint(pointer);
ArrayBubbleSort(array);
ArrayPrint(array);
ArrayPointerPrint(pointer);
return(EXIT_SUCCESS);
}
There are a whole lot of syntax errors in this program, and your code formatting doesn't exactly make it easy to read (for example, the indentation is very inconsistent).
The syntax error gives you the line number it failed on. You should look at that line, and maybe the lines immediately around that line, to determine what went wrong.
For example:
Pointers.c:32: error: expected ‘)’ before ‘array’
line 32:
void ArrayPrint(ArrayInt array){
The error gives you a clue, that something went wrong before array. The problem here is that ArrayInt is used as a type. You haven't defined this type anywhere.
Next, the syntax of your for loop is incorrect. The correct syntax is for (initial condition; condition; increment). Look at that carefully, and compare it to the syntax you used - notice the use of ;s rather than ,s, as well as their placement (See this question if you're interested.
I recommend you fix those, and then look hard at each error, and consult a book, web resource and/or Google to see how you're supposed to implement what you wrote down there (e.g. search for "c for loop syntax".. or "c array tutorial").
Now, if you're struggeling with these, you may want to try using the LLVM clang compiler, though it might be difficult to install if you can't find a linux package for it and/or you're not on a recent Mac OS X version. It outputs some nicer errors:
% clang -o foo foo.c
foo.c:17:9: warning: implicit declaration of function 'getpid' is invalid in C99
[-Wimplicit-function-declaration]
srand(getpid());
^
foo.c:25:18: warning: incompatible pointer to integer conversion assigning to
'int' from 'int *'; remove & [-Wint-conversion]
pointer[i] = &array[i];
^ ~~~~~~~~~
foo.c:23:18: warning: expression result unused [-Wunused-value]
for (i =0, i < SIZE_OF_ARRAY; i++;){
~ ^ ~~~~~~~~~~~~~
foo.c:19:16: warning: expression result unused [-Wunused-value]
for (i =0, i < SIZE_OF_ARRAY; i++;){
~ ^ ~~~~~~~~~~~~~
foo.c:32:17: error: unknown type name 'ArrayInt'
void ArrayPrint(ArrayInt array){
^
foo.c:35:12: error: expected ';' in 'for' statement specifier
for (i =0, int < SIZE_OF_ARRAY; i++;){
^
foo.c:35:12: error: expected expression
foo.c:35:38: error: expected ')'
for (i =0, int < SIZE_OF_ARRAY; i++;){
^
foo.c:35:7: note: to match this '('
for (i =0, int < SIZE_OF_ARRAY; i++;){
^
foo.c:35:39: error: expected expression
for (i =0, int < SIZE_OF_ARRAY; i++;){
^
foo.c:44:24: error: unknown type name 'ArrayInt'
void ArrayPointerPrint(ArrayInt array){
^
foo.c:47:36: error: expected ';' in 'for' statement specifier
for (i =0, i < SIZE_OF_ARRAY; i++){
^
foo.c:48:29: error: use of undeclared identifier 'pointer'
printf("%d : %10d \n",i,pointer[i]);
^
foo.c:47:16: warning: expression result unused [-Wunused-value]
for (i =0, i < SIZE_OF_ARRAY; i++){
~ ^ ~~~~~~~~~~~~~
foo.c:56:22: error: unknown type name 'ArrayInt'
void ArrayBubbleSort(ArrayInt array){
^
foo.c:78:24: error: unknown type name 'ArrayPtr'
void PointerBubbleSort(ArrayPtr pointer){
^
5 warnings and 10 errors generated.
Try to resolve those, and then continue reading. I'll mark the rest as a spoiler so that you can give it a go first.
.
.
.
Here:
for (i =0, int < SIZE_OF_ARRAY; i++;){
you just randomly put int where i should probably go, once you've fixed your for loop syntax.
void ArrayPointerPrint(int* array){
int i;
for (i =0; i < SIZE_OF_ARRAY; i++){
printf("%d : %10d \n",i,pointer[i]);
Here: what's pointer supposed to be, asks the compiler? It exists neither in the function's scope, nor in the global scope. I guess you meant array.
temp = *array+(j-1);
Why aren't you just using array[j-1] here? While it might work in this particular line, when you try to use the same on the left hand side of the assignment it certainly doesn't. You've also got some extra brackets in this area.
The code below compiles for me. There are still some warnings left though. You should google them.
#include <stdio.h>
#include <stdlib.h>
#define SIZE_OF_ARRAY 5
//=============================================================================
int *IntegerPtr;
int ArrayInt[SIZE_OF_ARRAY];
int *ArrayPtr[SIZE_OF_ARRAY];
//-----------------------------------------------------------------------------
void ArrayInitialize(int *array,int *pointer){
int i;
srand(getpid());
for (i =0; i < SIZE_OF_ARRAY; i++){
array[i] = (int)rand();
for (i =0; i < SIZE_OF_ARRAY; i++){
pointer[i] = &array[i];
}
}
}
//-----------------------------------------------------------------------------
void ArrayPrint(int* array){
int i;
for (i =0; i < SIZE_OF_ARRAY; i++){
printf("%d : %10d \n",i,array[i]);
}
printf("\n");
}
//-----------------------------------------------------------------------------
void ArrayPointerPrint(int* array){
int i;
for (i =0; i < SIZE_OF_ARRAY; i++){
printf("%d : %10d \n",i,array[i]);
}
printf("\n");
}
//-----------------------------------------------------------------------------
void ArrayBubbleSort(int* array){
int i;
int j;
int temp;
for( i = (SIZE_OF_ARRAY - 1); i >= 0; i-- )
{
for( j = 1; j <= i; j++ )
{
if( *(array+(j-1)) > *(array+j))
{
temp = *array+(j-1);
array[j-1] = array[j];
array[j] = temp;
}
}
}
}
//-----------------------------------------------------------------------------
void PointerBubbleSort(int* pointer){
int i;
int j;
int temp;
for( i = (SIZE_OF_ARRAY - 1); i >= 0; i-- )
{
for( j = 1; j <= i; j++ )
{
if( *(pointer+(j-1)) > *(pointer+j))
{
temp = *pointer+(j-1);
pointer[j-1] = pointer+(j);
pointer[j] = temp;
}
}
}
}
//-----------------------------------------------------------------------------
int main(void) {
int array[SIZE_OF_ARRAY];
int pointer[SIZE_OF_ARRAY];
ArrayInitialize(array,pointer);
ArrayPrint(array);
PointerBubbleSort(pointer);
ArrayPointerPrint(pointer);
ArrayBubbleSort(array);
ArrayPrint(array);
ArrayPointerPrint(pointer);
return(EXIT_SUCCESS);
}
Two of your problems are:
for (i =0, i < SIZE_OF_ARRAY; i++;){
array[i] = (int)rand();
for (i =0, i < SIZE_OF_ARRAY; i++;){
In both the loops, the comma should be a semicolon and the final semicolon should be missing. As it is, you have an assignment (i = 0 followed by an unused comparison i < SIZE_OF_ARRAY) and the loop condition is i++ != 0 (which takes a long time to become false; you've probably crashed long before it does become false), and there is no reinitialize step. You also don't really want two nested loops both indexing on i — use i and j, instead. Thus, if you need nested loops, you write:
for (i = 0; i < SIZE_OF_ARRAY; i++)
{
array[i] = (int)rand();
for (i = 0; j < SIZE_OF_ARRAY; j++)
{
However, it looks to me like there's no need for nested loops at all:
for (i = 0; i < SIZE_OF_ARRAY; i++)
{
array[i] = rand();
pointer[i] = &array[i]; // More on this in a moment
}
The compiler is also diagnosing a problem with the assignment:
pointer[i] = &array[i];
You're assigning a pointer (&array[i]) to an int (because int *pointer means that pointer is a pointer to an int so pointer[i], equivalent to *(pointer + i), is an int). Judging from the code, it looks like in main() you should be declaring:
int *pointer[SIZE_OF_ARRAY];
and the function interface should be:
void ArrayInitialize(int *array, int **pointer)
but all sorts of other parts of the code are inconsistent with that. I'm sure it can be made consistent; the question is which way to make it consistent. There isn't a reason to use pointer at all (that I can see) unless it is int **pointer in the function.
You have another variant of the loop syntax problems at:
for (i =0, int < SIZE_OF_ARRAY; i++;){
That too should be:
for (i = 0; i < SIZE_OF_ARRAY; i++){
In the other functions, you are using the names ArrayInt and ArrayPtr as if they are typedef names, but they're actually (unused) global variables. If you make them into typedefs after all, use them consistently. If you aren't going to make them into typedefs, then get rid of them and fix the function definitions.
You have unmatched parentheses in the sort functions where you swap:
temp = *array+(j-1));
*array+(j-1)) = array+(j));
*array+(j) = temp;
The notation you're using is weird; why not just use array indexes?
temp = array[j-1];
array[j-1] = array[j];
array[j] = temp;
Working code
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define SIZE_OF_ARRAY 5
typedef int *IntegerPtr;
typedef int ArrayInt[SIZE_OF_ARRAY];
typedef int *ArrayPtr[SIZE_OF_ARRAY];
void PointerBubbleSort(ArrayPtr pointer);
void ArrayBubbleSort(ArrayInt array);
void ArrayPointerPrint(ArrayPtr pointer);
void ArrayPrint(ArrayInt array);
void ArrayInitialize(ArrayInt array, ArrayPtr pointer);
void ArrayInitialize(ArrayInt array, ArrayPtr pointer)
{
int i;
srand(getpid());
for (i = 0; i < SIZE_OF_ARRAY; i++)
{
array[i] = (int)rand();
pointer[i] = &array[i];
}
}
void ArrayPrint(ArrayInt array)
{
int i;
for (i = 0; i < SIZE_OF_ARRAY; i++)
{
printf("%d : %10d \n", i, array[i]);
}
printf("\n");
}
void ArrayPointerPrint(ArrayPtr pointer)
{
int i;
for (i = 0; i < SIZE_OF_ARRAY; i++)
{
printf("%d : %10d \n", i, *pointer[i]);
}
printf("\n");
}
void ArrayBubbleSort(ArrayInt array)
{
int i;
int j;
int temp;
for (i = (SIZE_OF_ARRAY - 1); i >= 0; i--)
{
for (j = 1; j <= i; j++)
{
if (array[j-1] > array[j])
{
temp = array[j-1];
array[j-1] = array[j];
array[j] = temp;
}
}
}
}
void PointerBubbleSort(ArrayPtr pointer)
{
int i;
int j;
int *temp;
for (i = (SIZE_OF_ARRAY - 1); i >= 0; i--)
{
for (j = 1; j <= i; j++)
{
if (*pointer[j-1] > *pointer[j])
{
temp = pointer[j-1];
pointer[j-1] = pointer[j];
pointer[j] = temp;
}
}
}
}
int main(void)
{
ArrayInt array;
ArrayPtr pointer;
ArrayInitialize(array, pointer);
ArrayPrint(array);
PointerBubbleSort(pointer);
ArrayPointerPrint(pointer);
ArrayBubbleSort(array);
ArrayPrint(array);
return(EXIT_SUCCESS);
}
Sample output
0 : 881325466
1 : 1242393703
2 : 927466540
3 : 1493827854
4 : 533425101
0 : 533425101
1 : 881325466
2 : 927466540
3 : 1242393703
4 : 1493827854
0 : 533425101
1 : 881325466
2 : 927466540
3 : 1242393703
4 : 1493827854
Revised code
Minor tweaks to the code to adhere to the letter of the assignment. In particular, it uses the otherwise unused type definition for 'pointer to integer' to build the 'array of five pointers to integer'. It tries to get the output format to match the question's output precisely. Try to avoid trailing spaces on output lines (and source code lines).
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
enum { SIZE_OF_ARRAY = 5 };
typedef int *IntPtr;
typedef int ArrayInt[SIZE_OF_ARRAY];
typedef IntPtr ArrayPtr[SIZE_OF_ARRAY];
void PointerBubbleSort(ArrayPtr pointer);
void ArrayBubbleSort(ArrayInt array);
void ArrayPointerPrint(ArrayPtr pointer);
void ArrayPrint(ArrayInt array);
void ArrayInitialize(ArrayInt array, ArrayPtr pointer);
void ArrayInitialize(ArrayInt array, ArrayPtr pointer)
{
srand(getpid());
for (int i = 0; i < SIZE_OF_ARRAY; i++)
{
array[i] = rand();
pointer[i] = &array[i];
}
}
void ArrayPrint(ArrayInt array)
{
for (int i = 0; i < SIZE_OF_ARRAY; i++)
printf("%2d : %10d\n", i, array[i]);
}
void ArrayPointerPrint(ArrayPtr pointer)
{
for (int i = 0; i < SIZE_OF_ARRAY; i++)
printf("%2d : %10d\n", i, *pointer[i]);
}
void ArrayBubbleSort(ArrayInt array)
{
for (int i = (SIZE_OF_ARRAY - 1); i >= 0; i--)
{
for (int j = 1; j <= i; j++)
{
if (*(array + j-1) > *(array + j))
{
int temp = *(array + j-1);
*(array + j-1) = *(array + j);
*(array + j) = temp;
}
}
}
}
void PointerBubbleSort(ArrayPtr pointer)
{
for (int i = (SIZE_OF_ARRAY - 1); i >= 0; i--)
{
for (int j = 1; j <= i; j++)
{
if (*pointer[j-1] > *pointer[j])
{
int *temp = pointer[j-1];
pointer[j-1] = pointer[j];
pointer[j] = temp;
}
}
}
}
int main(void)
{
ArrayInt array;
ArrayPtr pointer;
ArrayInitialize(array, pointer);
puts("---- Initialized array of integers ----");
ArrayPrint(array);
PointerBubbleSort(pointer);
puts("---- Sorted array of pointers ----");
ArrayPointerPrint(pointer);
ArrayBubbleSort(array);
puts("---- Sorted array of integers ----");
ArrayPrint(array);
puts("---- Array of pointers ----");
ArrayPointerPrint(pointer);
return(EXIT_SUCCESS);
}
Revised output
---- Initialized array of integers ----
0 : 974520281
1 : 2052070745
2 : 565640395
3 : 1955497143
4 : 950748713
---- Sorted array of pointers ----
0 : 565640395
1 : 950748713
2 : 974520281
3 : 1955497143
4 : 2052070745
---- Sorted array of integers ----
0 : 565640395
1 : 950748713
2 : 974520281
3 : 1955497143
4 : 2052070745
---- Array of pointers ----
0 : 974520281
1 : 2052070745
2 : 565640395
3 : 1955497143
4 : 950748713