I am trying to make a program that takes 10 numbers as input and outputs them in reverse order using pointers in C.
#include<stdio.h>
#define N 10
int array[N]; //Global variable
int main(void) {
int j;
int i;
printf("Enter 10 numbers: ");
for (i=0;i<N;i++) {
scanf("%d",(array+(4*i))); //Works
}
for (j=N-1;j<0;j--) {
printf("%d",array[j]); //Doesn't print, using *(array+j*4) doesn't
//print also
}
printf("\n");
printf("%d\n",*(array)); //Works so scanf works
printf("%d\n",*(array+4)); //Works so scanf works
return 0;
}
I have tried a making a seperate function for the two for loops but still it doesn't work. I want to know WHY this for-loop doesn't print but the two printfs below it print.
EDIT:
My new code is
#include<stdio.h>
#define N 10
int array[N]; //Global variable
int main(void) {
int j;
int i;
printf("Enter 10 numbers: ");
for (i=0;i<N;i++) {
scanf("%d",(array+i)); //Works
}
for (j=N-1;j<0;j--) { //it is supposed to be j>=0 or j>0 WHY
printf("%d",array[j]); //Doesn't print, using *(array+j) doesn't
//print also
}
printf("\n");
printf("%d\n",*(array)); //Works so scanf works
printf("%d\n",*(array+1)); //Works so scanf works
return 0;
}
Thanks to all the posts, I have a better understanding of how indexing works in C now but the printf doesn't work still unless I change the for-loop conditions(see above). WHY doesn't it work with the initial conditions but with the latter conditions.
Whoa!
This:
scanf("%d",(array+(4*i))); //Works
is very wrong and is overwriting memory! Why are you multiplying the index? You don't need to do that, C can index by itself. It should just be:
scanf("%d", &array[i]);
You want the address of the i:th array member, so say that, don't beat around the bush with strange multiplications.
If you really want to be "using pointers", as mentioned in a comment, you can do so:
scanf("%d", array + i);
This works since array is a pointer to the first element of the array, and adding i to is a fully valid use of pointer arithmetic; C will compute the proper pointer, knowing the size of each int in the array.
Your array consists of 10 elements with type int (obviously). In expression array + i variable i is not an offset in bytes. It is an index of element. So when you read it like you do (scanf("%d",(array+(4*i)))) you basicly read array[0], array[4], array[8], array[12] (we're out of array bounds here already, it causes memory corruption and might cause crashes), etc. Elements array[1],[2],[3],[5], etc. are uninitialized. That's why your code doesn't work :)
UPDATE:
And #shilong-liu's note about array indices is important, too. I didn't notice it.
for (j=N-1;j<0;j--) {
printf("%d",array[j]); //Doesn't print, using *(array+j*4)
}
the for loop is not right. The correct one is that
for (j = N - 1; j > 0; j--)
I guess since the pointer used is of type int, you assume that you have to multiply i by 4 because depending on the compiler int is 4 bytes. I guess if you really care only about the output, then you could do it the way you did with reverse iteration.
What you have to do has been already mentioned by the others so I will give you my solution for actually swapping the pointers memory wise and you could choose from the given solutions:
#include<stdio.h>
#define N 10
int array[N]; //Global variable
int main(void) {
int j;
int i;
printf("Enter 10 numbers: ");
for (i=0; i<N; i++) {
scanf("%d", (array + i));
}
for (left = 0; left < N / 2; left++)
{
int right = N - left - 1;
int temporary = array[left];
array[left] = array[right];
array[right] = temporary;
}
for (i=0; i<N; i++) {
printf("%d", (array + i));
}
return 0;
}
I have been programming for algorithmic contests so you could trust me.
Related
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
void main()
{
int i=0,pos;
int *ptr;
clrscr();
ptr=(int *)malloc(10*sizeof(int));
printf("Enter 10 Elements:\n");
while(i<10)
{
scanf("%d",&ptr[i]);
i++;
}
printf("Current Array:\n");
for(i=0;i<10;i++)
{
printf("%d\t",ptr[i]);
}
printf("Enter the position to be deleted:");
scanf("%d",&pos);
for(i=pos;i<10;i++)
{
ptr[pos-1]=ptr[pos];
pos++;
}
for(i=0;i<10;i++)
{
printf("%d\t",ptr[i]);
}
getch();
}
Array i enter : 1 2 3 4 5 6 7 8 9 0
Suppose 4th position has been deleted
Array after deletion: 1 2 3 5 6 7 8 9 0 0
How can i make the program to print only 9 integers but without decresing the times the loop run.
i.e. without using
for(i=0;i<9;i++)
C doesn't allow you to do that. So, alternative is to dynamically allocate an array, put what you want in it, then when you get the size you want, transfer that data to a newly allocated array of the appropriate size and delete the old one.
Use a variable to keep track of how many elements of the array are being used.
When you start:
unsigned num_elements = 10;
int *ptr = malloc(num_elements * sizeof(int));
When you delete, do the following as well:
--num_elements;
When you print:
for (unsigned i=0; i<num_elements; ++i) {
...
}
Since you print the array in multiple places in the code, it would be nice to create a small function to do it.
void print_array(int *a, unsigned size) {
if (size == 0) {
printf("[empty]\n");
return;
}
printf("%d", a[0]);
for (unsigned i=1; i<size; ++i) {
printf("\t%d", a[i]);
}
printf("\n");
}
print_array(ptr, num_elements);
Your questions refers to 2 issues here:
Deleting an element of an dynamically allocated array
Printing values of an dynamically allocated array without adjusting for loop parameters
1)
for(i=pos;i<10;i++)
{
ptr[pos-1]=ptr[pos];
pos++;
}
Does not decrease the array at all - you just overwrite the particalur position with another element but you still have memory allocated for 10 int
One way to reach that would be using realloc after you moved the values by to the left beginning at the target element:
for (i = pos; i < array_size - 1; i++)
{
ptr[i] = ptr[i+1];
}
ptr = realloc(ptr, --array_size)
To 2)
Simple answer: This wont be possible. When you decrease the size of your array and dont adjust the loop's paramter you will access memory which doesnt belong to the array anymore.
Of course you dont want to adjust every for-loop by hand but you can simplify life if you always remember the array's size, preferably in immediate reference to it within a struct:
typedef struct
{
size_t size;
int *array;
} my_array_t;
If you ensure that size is properly adjusted everytime you allocate the array's memory (functions are your friend), you can always print the values with:
my_array_t a;
a.size = 10;
a.array = malloc(a.size * sizeof(int));
for (i=0; i < a.size; i++)
// ...
I'm trying to write a program that analyzes a (3 x 4) matrix of strings provided by the user. Ultimately, it needs to output the longest string present in the matrix, along with that string's length.
My program seems to read the input correctly, as judged its success in echoing back the input strings, but it does not correctly output the longest word. I'm sure I'm committing some kind of pointer-related error when I pass the value of longest word, but I do not have any idea how to solve it.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define M 4
#define N 5
#define MAX_DIM 20
void findMAX(char matrice[N][M][MAX_DIM]) {
char maxr;
int index;
int i, j, it;
index = 0;
maxr = *(*(*(matrice+0)+0)+MAX_DIM);
for (i = 0; i < N-1; i++) {
for (j = 0; j < M-1; j++) {
if (index < strlen(matrice[i][j])) {
index = strlen(matrice[i][j]);
// I save the longer line's value
it = i;
// I save the maximum's value
maxr = *(*(*(matrice+i)+j)+MAX_DIM);
}
}
}
printf ("The MAX is: -/%s/- and it's long: -/%d/- \n", maxr, index);
printf ("It is content in the: %d line, which is: \n", it);
for (j = 0; j < N-1; j++) {
printf("%s ", matrice[it][j]);
}
}
void leggi(char matrice[N][M][MAX_DIM]) {
int i, j;
for (i = 0; i < N-1; i++) {
for (j = 0; j < M-1; j++) {
printf ("Insert the element matrix [%d][%d]: ", i, j);
scanf ("%s", matrice[i][j]);
fflush(stdin);
}
}
}
void stampa(char matrice[N][M][MAX_DIM]) {
int i, j;
printf("\n(4 x 3) MATRIX\n");
for (i = 0; i < N-1; i++) {
for (j = 0; j < M-1; j++) {
printf("%s ", matrice[i][j]);
}
printf("\n\n");
}
}
int main(int argc, char *argv[]) {
char matrix[N][M][MAX_DIM]; //Matrix of N*M strings, which are long MAX_DIM
printf("************************************************\n");
printf("** FIND THE LINE WITH THE MAXIMUM ELEMENT **\n");
printf("** IN A (4 x 3) MATRIX **\n");
printf("************************************************\n");
printf ("Matrix Reading & Printing\n");
leggi (matrix);
stampa (matrix);
findMAX(matrix);
return 0;
}
First of all to address some misconceptions conveyed by another answer, consider your 3D array declared as
char matrix[N][M][MAX_DIM];
, where N, M, and MAX_DIM are macros expanding to integer constants.
This is an ordinary array (not a variable-length array).
If you want to pass this array to a function, it is perfectly acceptable to declare the corresponding function parameter exactly the same way as you've declared the array, as indeed you do:
void findMAX(char matrice[N][M][MAX_DIM])
But it is true that what is actually passed is not the array itself, but a pointer to its first element (by which all other elements can also be accessed. In C, multidimensional arrays are arrays of arrays, so the first element of a three-dimensional array is a two-dimensional array. In any case, that function declaration is equivalent to both of these:
void findMAX(char (*matrice)[M][MAX_DIM])
void findMAX(char matrice[][M][MAX_DIM])
Note in particular that the first dimension is not conveyed. Of those three equivalent forms, I find the last clearest in most cases.
It is quite odd, though, the way you access array elements in your findMAX() function. Here is the prototypical example of what you do:
maxr = *(*(*(matrice+i)+j)+MAX_DIM);
But what an ugly and confusing expression that is, especially compared to this guaranteed-equivalent one:
maxr = matrice[i][j][MAX_DIM];
Looking at that however, and it how you are using it, I find that although the assignment is type-correct, you are probably using the wrong type. maxr holds a single char. If you mean it to somehow capture the value of a whole string, then you need to declare it either as an array (into which you will copy strings' contents as needed), or as a pointer that you will set to point to the string of interest. The latter approach is more efficient, and I see nothing to recommend the former for your particular usage.
Thus, I think you want
char *maxr;
... and later ...
maxr = matrice[0][0];
... and ...
maxr = matrice[i][j];
That sort of usage should be familiar to you from, for example, your function stampo(); the primary difference is that now you're assigning the expression to a variable instead of passing it directly to a function.
And it turns out that changing maxr's type that way will correct the real problem here, which #AnttiHaapala already pointed out in comments: this function call ...
printf ("The MAX is: -/%s/- and it's long: -/%d/- \n", maxr, index);
requires the second argument (maxr) to be a pointer to a null-terminated array of char in order to correspond to the %s directive in the format string. Before, you were passing a single char instead, but with this correction you should get mostly the expected result.
You will probably, however, see at least one additional anomaly. You final loop in that function has the wrong bound. You are iterating with j, which is used as an index for the second dimension of your array. That dimension's extent is M, but the loop runs to N - 1.
Finally, I should observe that it's odd that you allocate space for a 5 x 4 array (of char arrays) and then ignore the last row and column. But that's merely wasteful, not wrong.
Try something like this:
void findMAX(char matrice[N][M][MAX_DIM]){
// char maxr
char maxr[MAX_DIM];
int index;
int i, j, it;
index = 0;
// maxr = *(*(*(matrice+0)+0)+MAX_DIM);
strncpy(maxr, *(*(matrice+0)+0), MAX_DIM);
for (i = 0; i < N-1; i++)
{
for (j = 0; j < M-1; j++)
{
if (index < strlen(matrice[i][j]))
{
index = strlen(matrice[i][j]);
it = i;
// maxr = *(*(*(matrice+i)+j)+MAX_DIM);
strncpy(maxr, *(*(matrice+i)+j), MAX_DIM);
}
}
}
printf ("The MAX is: -/%s/- and it's long: -/%d/- \n", maxr, index);
printf ("It is content in the: %d line, which is: \n", it);
// for (j = 0; j < N-1; j++){
for (j = 0; j < M-1; j++){
printf("%s ", matrice[it][j]);
}
}
It's possible to pass multi-dimensional arrays to C functions if the size of the minor dimensions is known at compile time. However the syntax is unacceptable
void foo( int (*array2d)[6] )
Often array dimensions aren't known at compile time and it is necessary to create a flat array and access via
array2D[y*width+x]
Generally it's easier just to use this method even if array dimensions are known.
To clarify in response to a comment, C99 allows passing of variable size arrays using the more intuitive syntax. However the standard isn't supported by Microsoft's Visual C++ compiler, which means that you can't use it for many practical purposes.
#include<stdio.h>
#include <stdlib.h>
int main()
{
int n,small=0,large=0,s,l,temp;
printf("this should work");
scanf("%d",&n);
// printf("%d",n);//
int a[n];
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
/* for(int i=0;i<n;i++)
printf("%d",a[i]);*/
small=a[0];
large=a[n-1];
for(int i=0;i<n;i++)
{
if(a[i]<small && i!=0)
{
small=a[i];
s=i;
}
if(a[i]>large && i!=n-1)
{
large=a[i];
l=i;
}
}
temp=a[s];
a[s]=a[l];
a[l]=a[s];
for(int i=0;i<n;i++)
printf("%d ",a[i]);
return 0;
}
This is a simple program to swap the largest and smallest number in an array and print the new array.
When I tried to run this program I got a segmentation fault.
Usually, a segmentation fault occurs when we try to access an out of bound memory location.
So I added printf statements to find out where the error is.
But none print statements were executed. what is the error here ?
One problem is that you don't actually set s and l to anything unless you find an element that is smaller/larger than the current one.
That means (for example), if the first element is the smallest, s will be set to some arbitrary value and trying to index the array with it could be problematic.
To fix that, where to set small and large, you should also set:
s = 0;
l = n - 1;
In addition, your swap code is wrong and should be:
temp = a[s];
a[s] = a[l];
a[l] = temp;
You should initialize s and l to some value because when the if condition does not works their values will remain uninitialized garbage values. Hence, a[l] or a[s] will not work, since these indexes are undefined values. That is why you will get segmentation fault because you are accessing an undefined area of an array.
So, use random values within array range like s=0,l=0 to initialize the variables or you can add some flags to check if the conditions are working.
if (l != 0 && s != 0) {
temp=a[s];
a[s]=a[l];
a[l]=a[s];
}
Also, I think you are swapping the values so in the last line a[l]=temp instead of a[l]=a[s].
ideone link
You cannot declare an array based on a dynamic size, unless the compiler supports it and even then it is generally not portable.
int a[n]
you actually need to use malloc or calloc.
int *a;
a = (int *)malloc(n * sizeof(int)); or a = (int *)calloc(n, sizeof(int));
I have some code to generate an array of size [user_input] in a function called array_generator, using size of array from scanf in main(), and then filling it with the numbers 0 to user_input (0, 1, 2, 3, if user input is 4). The array fills correctly as printf prints
`The array contains the value 1`
`The array contains the value 2`
`The array contains the value 3`, etc.
However when I pass the array to main and printf the array values I get equal statements filled with garbage numbers. I'm also 90% sure I have been passing the arrays and pointers incorrectly (new to them).
The code is below:
#include <stdio.h>
int *array_generator(int number_songs);
int main(void)
{
int input;
int *p;
int i;
int x;
printf("Enter number of songs wanted in random playlist: ");
scanf("%d", &input);
p = array_generator(input);
x = *p;
for (i = 0; i < input; i++)
{
printf("The array contains the values %d\n", x);
}
return 0;
}
int *array_generator(int n)
{
int a[n];
int *p;
int i;
for (i = 0; i < n; i++)
{
a[i] = i;
printf("The array contains the values %d\n", i);
}
return p = &a[n];
}
One simple solution is to define an array which is bigger than the largest list of songs reasonably possible. For example, since you print every entry, more than a few hundred are not reasonable. On a modern computer space is abundant. You would have a define for the max size on top of the prog, or later in some header:
#define MAX_SONGLIST_LEN 1000
The array can be global, or it can be static inside the function. Let's make it static because you want the function to return the address.
The change is minimal. Just say
static int a[MAX_SONGLIST_LEN];
You may want to change the loop and check for the max length as well:
for (i = 0; i < input && i < MAX_SONGLIST_LEN; i++)
inside array_generator() and main(). You also may want to inform your users about the maximum, and catch numbers which are too large. (You don't do any error handling of user input anyway -- what happens if the user enters a letter instead of a number? Look into the return value of scanf().)
The static array's life time is the lifetime of the program. It will be initialized to all zeroes by the way. If you want to randomly initialize it look at the rand() function.
You are correct in that you are using pointers wrong. The code below preforms the function that you want...
#include <stdio.h>
void array_generator(int n, int arr[]) {
for (int i = 0; i < n; i++) {
arr[i] = i;//array values
//printf("The array contains the values %d\n", i);
}
}
int main() {
int input;
printf("Enter number of songs wanted in random playlist: ");
scanf("%d", &input);
int array[input];//declare array with length of input
array_generator(input, array);
for(int i=0; i<sizeof(array)/sizeof(array[0]); i++) {//input could also be used at the limit to the for loop
printf("%d", array[i]);
}
printf("\n");
return 0;
}
What you are doing is you are over complicating your code. The first thing you do is you create a function and try to make it return an array. This is not necessary. All you need to do is pass a pointer to the array and all edits to the array will be made on the same scope as the array was declared on.
You also mentioned that you want to find the size of an array. This can be done with array *a of any type and sizeof(a)/sizeof(a[0]). This works by returning the number of bytes used by the array divided by the number of bytes used by the first element in the array.
One more thing that you have that you don't need is x = *p;. when you do this, you are essentially doing this x=*p=array_gen(input);
More information on pointers in C can be found here.
I've written a program to recursively sort an array.
However, I get the following error on line 11: syntax error before ']' token.
Here is the code:
//This program recursively sorts an array
#include<stdio.h>
void rec_sort(int values[], int n);
main()
{
int vals[4];
vals[0] = 37; vals[1] = 48; vals[2] = 56; vals[3] = 63;
printf("this array sorted: %x\n", rec_sort(vals[], 4));
system("Pause");
return 0;
}
void rec_sort(int values[], int n) {
//Base case
if (n<2) return;
int maxIndex=0;
int i;
//Find max item in array in indexes 0 through n-1
for(i=1; i<n;i++) {
if(values[i] > values[maxIndex])
maxIndex=i;
}
//Swap this element with one stored in n-1
//Set temp to n-1, set n-1 in array to max, set max to temp
int temp = values[n-1]; //Store temp as last element in array
values[n-1] = values[maxIndex]; //Store last element as max value in array
values[maxIndex] = temp; //temp will keep on changing, as array is sorted
//Recursively sort the array values of length n-1
sort(values, n-1);
}
It looks like you're trying print out the whole array, which C won't do in one call to printf. Instead, you need a loop to iterate through the array and print out each number individually:
for (i=0; i<4; i++)
printf("%x\n", vals[i]);
Since rec_sort isn't returning the array, you also need to invoke it separately from the call the printf, so you'd get something like:
// sort the data:
rec_sort(vals, 4);
// print the sorted values:
for (i=0; i<4; i++)
printf("%x\n", vals[i]);
Just remove the [] on line 11. But this is a naive answer to your question, and won't get you far. There are other problems - the most obvious is the idea of printf(..., rec_sort(...)...);
Considering rec_sort has void return type, how do you expect printf() to understand what to do? I am not sure what you want either, but this should be at least a start for you.
printf("this array sorted: %x\n", rec_sort(vals[], 4));
but rec_sort() is void. Doesn't return anything
void rec_sort(int values[], int n)
Also, declare your main as int main()
The problem is in this:
rec_sort(vals[], 4)
What exactly do you want to do there? The [] is an index operation, so either you need to put a number in there, or you leave them out completely (if you want to talk about the whole array).
The first thing you should do is remove the square brackets:
printf("this array sorted: %x\n", rec_sort(vals, 4));
Second, note that rec_sort returns void, so you cant use the return value
you need
int i; // at the top of the main
// ...
rec_sort(vals, 4);
printf("this array sorted: ");
for(i = 0; i < 4; ++i) printf("%x ", vals[i]);
printf("\n");
Third: you need to call rec_sort again
Fourth: what are you tryin to do with the system statement?