Print descending array C - arrays

I have to create functions for print array, fill array witn descending numbers.
I created functions for printing array and creating descending array.But I faced with a problem.
If I use my own function printArray() it prints something unclear. Where is the problem, what i do wrong?
Please, help.
Here is the code in C. value - is value of array
Function for printing array:
void printArray (int arr[]){
int i;
printf("\n");
for(i = 0; i < value; i ++)
printf("%3d ", arr[i]);
}
Function for creating descending array:
int createDescendingArray(int a[])
{
int i;
printf("\nDescending array is created.\n");
for (i = value; i > 0; i--) {
a[i] = i;
}
printArray(a); // print of created array
}
Main function:
int main(){
int arr1[value]; //create new array
arr1[value] = createDescendingArray (arr1); //fill array with descending numbers
}
However when I don't use my print function in function createDescendingArray() and print it in Main funktion with standart method like this:
{int i;
for(i = 0; i < value; i++)
{
a[i]=i;
printf("%3d", a[i]);
}
}
It shows descending array as ascending (look at the picture)
How it works?

You have been using a variable named value in your function which prints array, without initializing it, hence the garbage value.
you should initialize it in the function or pass its start value as an argument to the function.
#include <stdio.h>
#include <stdlib.h>
void printArray(int *arr, int length)
{
int i;
printf("\n");
for (i = 0; i < length; i++)
{
printf("%3d ", arr[i]);
}
}
int *createDescendingArray(const int length)
{
if (length == 0)
return NULL;
int *a = malloc(length * sizeof(int));
;
printf("\nDescending array is created.\n");
for (int i = length-1; i >= 0; i--)
{
a[i] = i;
}
printArray(a, length); // print of created array
return a;
}
int main()
{
int *a = createDescendingArray(20);
printArray(a, 20);
return 0;
}
these changes should most probably do the trick but again, there is no initialization of value in the function that creates array as well
EDIT: stop creation of array if length is 0
EDIT2: fixed code to consider 0 as an element
EDIT3: Fixed code with suggestion from #CraigEstey in comments, tested and working
EDIT4: fixed for loop and removed cast on mallock

The function
int createDescendingArray(int a[])
{
int i;
printf("\nDescending array is created.\n");
for (i = value; i > 0; i--) {
a[i] = i;
}
printArray(a); // print of created array
}
is wrong.
According to the output in your question, it seems that you have defined value as 4 (you are not showing us the code with the definition). In that case, your code for the mentioned function is equivalent to the following:
int createDescendingArray(int a[])
{
printf("\nDescending array is created.\n");
a[4] = 4;
a[3] = 3;
a[2] = 2;
a[1] = 1;
printArray(a); // print of created array
}
I did nothing else to the code than unroll the loop.
Since the array a has a size of 4 elements, valid indices are from 0 to 3. Therefore, by writing to a[4], you are writing to the array out of bounds, causing undefined behavior.
If you had written
for (i = value - 1; i >= 0; i--)
instead of
for (i = value; i > 0; i--)
then the unrolled loop would be:
a[3] = 3;
a[2] = 2;
a[1] = 1;
a[0] = 0;
This is better, because now we have fixed the undefined behavior; you are no longer writing to the array out of bounds. However, this is still not what you want. If you want descending output, your unrolled loop must look like this instead:
a[0] = 3;
a[1] = 2;
a[2] = 1;
a[3] = 0;
This can be accomplished by changing your function to the following:
int createDescendingArray(int a[])
{
int i;
printf( "\nDescending array is created.\n" );
for ( i = 0; i < value; i++ ) {
a[i] = value - i - 1;
}
printArray(a); // print of created array
}
Here is a small test program:
#include <stdio.h>
//NOTE: It is customary for constants to be written upper-case,
//not lower-case, so the line below should normally not be used.
#define value 4
void printArray (int arr[]) {
int i;
printf( "\n" );
for( i = 0; i < value; i++ )
printf("%3d ", arr[i]);
}
int createDescendingArray(int a[])
{
int i;
printf( "\nDescending array is created.\n" );
for ( i = 0; i < value; i++ ) {
a[i] = value - i - 1;
}
printArray(a); // print of created array
}
int main( void )
{
int array[value];
createDescendingArray( array );
}
The output is:
Descending array is created.
3 2 1 0
In this test program, I took over most of your other code, but I did not take over the function main, because it was also causing undefined behavior:
int main(){
int arr1[value]; //create new array
arr1[value] = createDescendingArray (arr1); //fill array with descending numbers
}
In the line
arr1[value] = createDescendingArray (arr1);
you are assigning the return value of the function to a variable, although the function did not return a value. This causes undefined behavior. You may want to consider changing the return type to void in the function declaration, if it does not return a value.
Also, even if the function did return a value, arr1[value] would be writing to the array out of bounds, as valid indices are from 0 to value - 1.

Related

Does this code have anything to do with pointers?

Could somebody help me with this piece of code.
I have no idea that what it does.
#include <stdio.h>
int main()
{
int arr[5],i;
int a = 1, n = 5;
for (i=0; i<5;a+= arr[i++]);
int d = a;
printf("%d",d);
}
technically this code has pointers. That is because arrays are pointers to the values that are stored in it(arr[0-5]). Every Element of the array points to a Adress anywhere in the memory.
int main()
{
int arr[10];
unsigned int x;
for(x = 0; x < 9; x++)
{
arr[x] = x;
printf("%d ", *(arr+x));
}
return 0;
}
in this code you can see that you can use an pointer notation to navigate trough an array.
now to your second question. the code that you gave us here is first initializing a array with 5 elements, a int named 'i', a int named 'a' with the value 1, and a int named 'n' that has the value 5.
then you go into a for loop that repeats 5 times. in the for loop you give a the value of the array[i]. but because the array is not filled with numbers it comes a number that is anywhere in the memory.
next you give the variable 'd' the value of 'a'. and at least you print 'd'.
I think that you want it so that you go into a loop and it prints the elements of the array.
int main()
{
int arr[5], i, a = 1, d;
for(i = 0; i < 5; i++)
arr[i] = i;
for(i = 0; i < 5; i++)
{
a = arr[i];
d = a;
printf("%d ", d);
}
return 1;
}
i think that is what you want.
Of note, we've not put anything of interest into arr, however notice the semicolon on the end of this line:
for (i=0; i<5;a+= arr[i++]);
That's a succinct (confusing?) way of saying
for (i=0; i<5; i++)
{
a += arr[i];
}
So a is summing up whatever is in arr.

Array Rotation with Getting Max Value and Index Location of Array C language

I'm creating a program that gets the index value of the highest element in an array.
Sample Input:
4 (Size of a[])
1 2 4 3 (Elements of a[])
2 (Size of rotate[])
0 2 (Elemnts of rotate[])
Output will be:
2
0
Using left rotation.
In the First Rotation (0) the location will be 2 because 4 is the highest a[1,2,4,3]
In the Second Rotation (2) the location will be 0 because 4 is the highest a[4,3,1,2]
Problem is i'm not getting the desired output and there was a warning in for(j=0;j<rotateValue;j++)
I want the function to be as it is and to fix this part to int* output = getMaxIndex(a,rotate);
but i don't know how.
Thank you in advance for helping!
#include<stdio.h>
int i,j,k; // for looping
int n, m; // sizes of arrays
int getMaxIndex(int* a[], int* rotate[])
{
int indices[m];
for(i=0;i<m;i++)
{
int* rotateValue = rotate[i];
for(j=0;j<rotateValue;j++) // for rotation
{
int* first = a[0];
for(i=0;i<n-1;i++)
{
a[i] = a[i+1];
}
a[n-1] = first;
}
int location;
int* max = a[0];
for(j=0;j<n;j++) // getting the max element
{
if(a[j] > max)
{
max = a[j];
// printf("Max added");
}
}
for(j=0;j<n;j++) // getting the location
{
if(max == a[j])
{
location = j;
// printf("Loc added");
}
}
indices[i] = location;
}
// for(i=0;i<m;i++) // printing here to know if correct
// {
// printf("%d",indices[i]);
// }
return *indices;
}
int main()
{
scanf("%d",&n); // inputting array size
int* a[n];
for(i=0;i<n;i++) // filling elements of a[]
{
scanf("%d",&a[i]);
}
scanf("%d",&m); // inputting rotate array size
int* rotate[m];
for(i=0;i<m;i++) // filling elements of rotate[]
{
scanf("%d",&rotate[i]);
}
int* output = getMaxIndex(a,rotate); // call function
for(i=0;i<m;i++) // printing output
{
printf("%d",output[i]);
}
}
int getMaxIndex(int* a[], int* rotate[]);
Designing getMaxIndex() in the following way should solve most of the issues:
int* getMaxIndex(int a[], int rotate[])
{
static int indices[MAX_POSSIBLE_VALUE_OF_M];
/*
your code
*/
return indices;
}
Now, all you have to do is adjust your code in the main() function accordingly.
Why declare the array indices[] in getMaxIndex() as static int?
indices[] is a local variable of getMaxIndex(). And so after the return statement of getMaxIndex() is executed, it shall be destroyed. That means, if you return indices[] to main(), the main function will not be able to access indices[] anymore. And this issue can be solved by declaring indices[] as a static int instead of int.
NOTE: static array should have constant size. So, its size should be declared as maximum possible value of m instead of m.
Required adjustments in main():
Declare a[] and rotate[] as int instead of int*.
Check out my code.I am getting the correct output. I have written down a few mistakes that you have made.
void getMaxIndex(); //function declaration
int n, m; //for storing array size
int * a, * rotate;
int main(void) {
int i; //to use in loops
scanf("%d", & n); // inputting array size
a = (int * ) malloc(n * sizeof(int));
for (i = 0; i < n; i++) // filling elements of a[]
{
scanf("%d", & a[i]);
}
scanf("%d", & m); // inputting rotate array size
rotate = (int * ) malloc(m * sizeof(int));
for (i = 0; i < m; i++) // filling elements of rotate[]
{
scanf("%d", & rotate[i]);
}
getMaxIndex();
free(a);
free(rotate);
return 0;
}
void getMaxIndex() {
int i;
int aMax, rotateMax;
int aMaxIndex, rotateMaxIndex;
aMax = a[0];
rotateMax = rotate[0];
for (i = 1; i < n; i++) {
if (aMax < a[i]) {
aMax = a[i];
aMaxIndex = i;
}
}
for (i = 1; i < m; i++) {
if (rotateMax < rotate[i]) {
rotateMax = rotate[i];
rotateMaxIndex = i;
}
}
printf("%d\n%d", aMaxIndex, rotateMaxIndex);
}
My suggestions:
Always try to allocate memory for your array dynamically so that you can avoid errors such as Segmentation Fault or Core Dump.
In your code you have used array of pointers instead of pointers, there you went wrong. Try refering to your textbook or other sources to get a clear idea regarding pointers.
For example, in your code you passed your array named indices using the line:
return indices;
Now, to pass a pointer you don't need to use asterisk(). Simply write: return indices;
Also, don't use asterisk symbol to declare an array.
Your Code:
int* a[n];
Here you are declaring an array of pointers not an array.
Correct code:
int a[n];
But I liked your logic. You just have to implement it with the correct syntax. Just keep practicing.
I the code which I've written is understood by you, my work here is done. Happy Coding!!!

How to move one element to the left of a fixed array

int array[10] = {1,2,3,4,5}
from my understanding, the rest of the indexes that haven't been assign a value will be 0. If I want to move every element to the left (I am wanting to remove the first value i.e. index 0). How do I do this without causing duplicate values for the last index with a integer assigned?
For example:
current array
output: 1234500000
+1 to the left:
output: 2345500000
I tried the following code:
void order_array(int size, int array[])
{
for (int i = 0; i < size-1; i++)
{
if (array[i] == 0)
{
array[i-1] = 0;
}
array[i] = array[i+1];
}
}
expected output after method execution:
output: 2345000000
Also before someone says this is a duplicate, I have looked around and no thread explains with fixed arrays, i.e. with 0's as default values.
Appreciate your response.
if (array[i] == 0)
{
array[i-1] = 0;
}
I don't understand why this block is there. It's not possible to get inside the if statement.
With your expected output and given this is an array of ints, I suspect the solution is to only output four values in your print statement, but if the last element of the array should be zero, you can just do this after your for loop:
array[size-1] = 0;
If you don't want rotation then:
int arr[]; //initialize it
int siz=sizeof(arr)/sizeof(arr[0]);
int index=0;
while(index<siz-1)
{
arr[index]=arr[index+1];
index++;
}
arr[index]=0; //0 default value at the end of the array
This will work fine
You just need to manually set the last value to zero at the end. I'd also consider using the built-in memmove function which is designed for moving around data where the source and destination overlap.
void order_array(int size, int array[]){
memmove(array, array+1, (size-1) * sizeof(array[0]));
array[size-1] = 0;
}
#include <stdio.h>
#define ARRAY_SIZE 10
void order_array(int size, int* array) {
for (int i = 0; i < size; i++) {
if (!array[i]) {
continue;
}
if (i + 1 < size)
array[i] = array[i + 1];
}
}
int main() {
int array[ARRAY_SIZE] = {1, 2, 3, 4, 5};
printf("intput: ");
for (int i = 0; i < ARRAY_SIZE; i++) {
printf("%d", array[i]);
}
printf("\n");
order_array(ARRAY_SIZE, array);
printf("output: ");
for (int i = 0; i < ARRAY_SIZE; i++) {
printf("%d", array[i]);
}
printf("\n");
return 0;
}
Maybe you should consider the last value that not equal to default value 0.
Execute in shell:
gcc -o a.out a.c && ./a.out
intput: 1234500000
output: 2345000000

Possible to run through a c-array inside a function with only one pointer as parameter?

I'm playing and learning a little with C, created an array and passed it to a function together with its size so I can run through the array and print all its elements (so I gave the function two parameters: the array itself and its size).
But now I like to do all that just by passing one parameter to the function. I got it working a little by using a pointer but I don't know how to stop because I don't have any information about arrays length, it only works in the code below because I put the array length inside the for loop. But how would that work in general if I didn't know the size and only passed one parameter to the function?
I thought it might somehow be possible to realize if a pointer points outside of the array I'm currently working with, but is that even doable? :S
void printArray(int *p){
for(int i=0; i<4; i++){
printf("%d ", *(p+i));
}
}
int main(){
int myArray[4] = {8,4,1,1};
int *p = myArray;
printArray(p);
return 0;
}
The only way to traverse a pointed-to array without a length parameter is if the array contains a distinct terminator value.
For example, a C-string is "NULL-terminated" array of char values. You can traverse a char* because you know
to test for the presence of the '\0' character, which has an integer value of 0.
As it applies to the code in your question, you could use -1 as a terminator value, like so:
void printArray(int *p){
while (*p != -1{
printf("%d ", *p++);
}
}
Note however, that doing this requires that there is some way to interpret a valid int value as
"invalid" for your purposes.
In the main, it's much easier and simpler to just pass the length of the array to the function.
In addition to other mentioned approaches I can offer other two:
1) You can pass the length of array as the first element (like works some containers in Pascal):
#include <stdio.h>
void print_array(int *arr)
{
int length = arr[0];
for (int index = 1; index <= length; ++index)
printf("%d ", arr[index]);
printf("\n");
}
int main()
{
int length = 10;
int *arr = malloc(sizeof(int) * length);
arr[0] = length;
for (int index = 1; index <= length; ++index)
arr[index] = index * index * index;
print_array(arr);
free(arr);
return 0;
}
2) You can create a struct for your array (like is is done for std::vector in C++ STD with class):
#include <stdio.h>
typedef struct Array
{
int size;
int *data;
} Array;
void print_array(Array *arr)
{
for (int index = 0; index < arr->size; ++index)
printf("%d ", arr->data[index]);
printf("\n");
}
int main()
{
int length = 10;
Array *arr = malloc(sizeof(Array));
arr->data = malloc(sizeof(int) * length);
arr->size = length;
for (int index = 0; index < length; ++index)
arr->data[index] = index * index * index;
print_array(arr);
free(arr->data);
free(arr);
return 0;
}

How to reverse digits of each number in an array using pointer arithmetic

I tried to write a program in C that reverses all the numbers in an array, but it actually doesn't reverse anything, so I get unchanged numbers back. I guess I got something wrong with the pointers.
Here is my code:
#include <stdio.h>
void reverse(int *n) {
int number = *n, number2 = 0;
while (number!=0) {
number2 *= 10;
number2 += number % 10;
number /= 10;
}
*n = number2;
}
void ReverseDigits(int *p, int n) {
int i = 0;
while (i < n) {
reverse(&p);
p++;
i++;
}
}
int main() {
int array[3] = {123, 456, 789}, i = 0;
while (i < 3) {
ReverseDigits(array, 3);
i++;
}
return 0;
}
In ReverseDigits the variable p is an int pointer. When you do &p you'll get a pointer to int pointer. But your reverse function just expects an int pointer so your call of reverseis wrong. Simply do
reverse(p); // insteand of reverse(&p)
In main you shall not call ReverseDigits in a loop as the function already loops the array (i.e. the number of elements passed). So skip the while and simply do:
int main() {
int array[3] = {123, 456, 789};
ReverseDigits(array, 3);
return 0;
}
It seems to me that your reverse() function is "both baffling, and necessarily wrong." (Hey, don't take that personally...)
How could such a function possibly work, without being told, not only where the (array) is, but how long it is? You seem to be missing a parameter here.
Once you've settled that problem in your design, the task of "reversing" an array is simply a process of "swapping" the first-and-last elements in an algorithm that goes something like this: (pseudocode!)
function reverse( array[], array_size) {
int i = 0;
int j = array_size - 1; // since zero-based
while (i < j) { // no need to use "<=" here"
temp = array[i];
array[i] = array[j];
array[j] = temp;
i++;
j--;
}
}

Resources