Remove Negative numbers from array in C - c

I am trying to remove the negative numbers from array with the following code. Unfortunately, not getting the results. It just prints the first element over and over. Can someone please let me know where am I going wrong?
#include <stdio.h>
void removenegative(int a[],int *p, int *q);
int main()
{
int a[] = {2, 3, -5, -7, 6, 9};
int i;
int *p, *q;
p = a;
q = a+6-1;
removenegative(a, p,q);
for(i=0;i<6;i++)
{
printf("%2d", *p);
}
printf("\n");
}
void removenegative(int a[],int *p, int *q)
{
int *x;
x= &a[0];
while (p<=q)
{
if (*p>=0)
{
*x = *p;
x++;
}
p++;
}
for( ; x<=q; x++)
{
*x = -1;
}
}

for(i=0;i<6;i++)
{
printf("%2d", *p);
}
You're not changing p!

You are printing only one value:
printf("%2d", *p);
do this before for loop:
p = a;
and add p++ inside loop;

It just prints the first element over and over
Of course it does so...
for(i=0;i<6;i++)
{
printf("%2d", *p);
}
You always print *p, which is a[0]

Change:
printf("%2d", *p);
to:
printf("%2d", a[i]);
You're looping i, but not using it.

Your code is correct:
void removenegative(int a[],int *p, int *q)
{
int *x;
x= &a[0]; // let x point to the first thing in a
while (p<=q) // continue while p points to an address before q
{
if (*p>=0) // if the thing pointed to by p is greater than zero...
{
*x = *p; // copy from p to x, increment x
x++;
}
p++; // increment p
}
for( ; x<=q; x++) // while x is less than q...
{
*x = -1; // fill in -1
}
}
So x is an incrementing write pointer, while p scans the array and q acts as an end-of-array marker.
As I've been beaten to saying while typing this, your output routine is incorrect.

Related

Input matrix in C using function

I am trying to input a matrix of order p*q using a function I got some errors. how to get the input using a pointer it gives me a segmentation fault .
#include<stdio.h>
int read_matrix(int *x,int p,int q){
for(int i=0;i<p;i++){
for(int j=0;j<q;j++){
scanf("%d",*(x+i)+j);
}
}
return 0;
}
int main(){
int p,q;
printf("enter the order of the matrix");
scanf("%d%d",&p,&q);
int a[p][q];
read_matrix(a[q],p,q);
for(int i=0;i<p;i++){
for(int j=0;j<q;j++)
printf("%d",a[i][j]);
}
}
You have multiple problems and seem to misunderstand how arrays and pointers work. To begin with a[q] will be out of bounds if p <= q.
a[q] (if q is valid) is an array of q elements, which decays to a pointer to its first element. It's not any kind of pointer to the matrix itself.
And inside the read_matrix function when you do *(x + i) + j that is actually equal to x[i] + j which is a single int value, and not a pointer to an element in any array.
You need to pass the matrix itself to the function, and let it decay to a pointer to an array, and use that as a proper "array of arrays":
// Use variable-length arrays for the matrix argument x
// Declare it as a pointer to an array of q integer elements
// Note the changed order of arguments, it's needed because q must be declared
// before its used for the VLA
void read_matrix(int p, int q, int (*x)[q]) {
for (int i = 0; i < p; ++i) {
for (int j = 0; j < q; ++j) {
scanf("%d", &x[i][j]); // Use normal array indexing and address-of operator
}
}
}
int main(void) {
int p, q;
scanf("%d %d", &p, &q);
int a[p][q];
// Here a will decay to a pointer to its first element, &a[0]
// Since a[0] is an array of q elements, the type will be
// int (*)[q], exactly as expected by the function
read_matrix(p, q, a);
for (int i = 0; i < p; ++i) {
for (int j = 0; j < q; ++j) {
printf("%d ", x[i][j]);
}
printf("\n");
}
}
You are making things needlessly complicated with the pointer arithmetic. *(x+i)+j means x[i] + j*sizeof(int) which is not what you want.
Just do something like this instead:
#include<stdio.h>
void read_matrix(int x, int y, int matrix[x][y])
{
int count=0;
for(int i=0;i<x;i++)
for(int j=0;j<y;j++)
matrix[i][j] = ++count;
}
int main (void)
{
int x=3, y=2;
int matrix[x][y];
read_matrix(x,y,matrix);
for(int i=0;i<x;i++)
{
for(int j=0;j<y;j++)
printf("%d ",matrix[i][j]);
printf("\n");
}
}

sorting arrays in c with pointers

I am trying to sort an array from least to greatest using pointers instead of array subscripts. I am not sure where the problem is but when i run this code, the values are returned in the same order that they were entered. The find_largest and swap functions both do exactly what they say. The selection_sort function uses a for loop to sort the numbers from right to left (greatest to smallest, right to left). I have been staring at this for a while now and it looks like it should work fine but like i said, for some reason the numbers are returned in the same order they were entered.
Here is my code:
#include <stdio.h>
#define N 5
void selection_sort(int *a, int n);
int *find_largest(int *a, int n);
void swap(int *p, int *q);
int main(void)
{
int i;
int a[N];
printf("Enter %d numbers to be sorted: ", N);
for (i = 0; i < N; i++)
scanf("%d", (a+i));
selection_sort(a, N);
printf("In sorted order:");
for (i = 0; i < N; i++)
printf(" %d", *(a+i));
printf("\n");
return 0;
}
void selection_sort(int *a, int n)
{
int i = 0;
int *largest;
for(i = 0; i < n; i++){
largest = find_largest(a, n-i);
swap(largest, a+(n-1-i));
}
}
int *find_largest(int *a, int n){
int *p = a;
int *largest = p;
for(p = a; p < a+n-1; p++){
if(*(p+1) > *p){
largest = (p + 1);
}
}
return largest;
}
void swap(int *p, int *q){
int *temp;
temp = p;
p = q;
q = temp;
}
There are two mistakes in your code.
One, logical in the find_largest function:
int *find_largest(int *a, int n){
int *p = a;
int *largest = p;
for(p = a; p < a+n-1; p++){
if(*(p+1) > *largest){ <---- //here you were checking for *(p)
largest = (p + 1);
}
}
return largest;
}
the other is with pointers in swap function:
void swap(int *p, int *q){
int temp;
temp = *p;
*p = *q;
*q = temp;
}
As John Bollinger mentioned in the comments, swap() does not function correctly - all it does is reassign pointers that quickly go out of scope.
Here is a rewrite of that function that does work. Just swap it in and it fits perfectly.
void swap(int *p, int *q){
int temp;
temp = *p;
*p = *q;
*q = temp;
}
Thanks to John Bollinger.

C - How to make function return a pointer?

This function should return a pointer to the first occurrence of the largest int in an array without using the index operator. It can find and print the largest int, but how do I make it return a pointer? And how do I test if it was successful?
int *arr_first_max(const int *a, size_t n) {
const int *k;
int largest = 0;
for (k = a; *k != '\0'; k++) {
if (*k > largest) {
largest = *k;
}
}
printf("%d\n", largest);
return &largest;
}
Edit: size_t n is supposed to be used but I'm not sure how to include it.
And another answer assuming:
n is length of array a (in terms of elements, not bytes)
You want to iterate through the whole array a
Then code is:
const int *arr_first_max(const int *a, size_t n) {
const int *largest = a;
while(n--) {
if(*a>*largest)
largest = a;
a++;
}
printf("%d\n", *largest);
return largest;
}
In all functions n is assumed to be >0.
Just keep your logic, but instead of storing the max, store the index to the max, in order to return a pointer to the array at that index.
int *arr_first_max(const int *a, size_t n) {
int i,l;
for (l=i=0 ; i<n ; i++)
if (a[i] > a[l]) l = i;
return a+l;
}
Edit Pointer only version (based on comments) which does n-1 iterations
const int *arr_first_max(const int *a, size_t n) {
const int *most;
for (most=a++ ; --n ; a++) if (*a > *most) most = a;
return most;
}
And since I misread the question, a recursive bonus!
const int *arr_first_max_r(const int *most, const int *a, size_t n) {
if (*a > *most) most = a;
return --n ? arr_first_max_r(most, ++a, n) : most;
}
to be called like this
printf("Biggest int is : %d\n", *arr_first_max_r(a, a, n));
This works. You detect the largest number like you did then run the same loop again to see where the number is then return that address. I also changed some data types from int to const int and I removed the 2nd parameter because you're checking for null characters.
#include <stdio.h>
#include <stdlib.h>
const int *arr_first_max(const int *a) {
const int *k;
int largest=0;
for (k = a; *k != '\0'; k++) {
if (*k > largest){
largest = *k;
}
}
for (k = a; *k != '\0'; k++) {
if (*k == largest){
return k;
}
}
}
int main(){
int nums[6]={7,2,1,5,4,6};
const int* y=arr_first_max(nums);
printf("%d\n", *y);
}
Assuming
the function's signature is correct and complete (arr_first_max alludes that you search in an array for the first max element)
and thus int* a is the pointer to the first element (i.e. equivalent to int a[] in a signature); I'll leave the const specifier in this case, though I think you could omit/discard it if the exercise permits that
size_t n is the size of the array or, in other words, the number of elements in the array
you want to return a pointer to largest element in the array without using the subscript [] operator
then this would be a solution
int *arr_first_max(const int *a, size_t n) {
int *largest, *k;
for (largest = k = a; (k - a) < n; k++)
if (*k > *largest)
largest = k;
return largest;
}
That is because I quote from The C Programming Language:
Pointer subtraction is also valid: if p and q point to elements of
the same array, and p<q, then q-p+1 is the number of elements from
p to q inclusive.
i won't guess what size_t n is for
int *arr_first_max( int *a, size_t n) {
int *largest = a;
while(*a){
a++;
if(*a>*largest) largest=a;
}
return largest;
}

C Program, function sorting through pointers

This program is supposed to take an array, and sort it from lowest to highest value. My program won't sort any values though. I believe the error is in the selectionSort. The values i and j are present in the function, I printed them out inside the function but they are not passed into the swap function. I tried making i and j pointers but it didn't work. I just have no clue on what to do next. Any help would be appreciated.
#include <stdio.h>
#define N 5
void selectionSort(int *a, int n);
int *findLargest(int *a, int n);
void swap(int *p, int *q);
int main(void)
{
int i;
int a[N];
printf("Enter %d numbers: ", N);
for (i = 0; i < N; i++) {
scanf("%d", &a[i]);
}
selectionSort(a, N);
printf("In sorted order:");
for (i = 0; i < N; i++) {
printf(" %d", a[i]);
}
printf("\n");
return 0;
}
void selectionSort(int *a, int n)
{
int *p = a;
int i;
int j;
if (n == 1) {
return;
}
i = *(p+n-1);
j = *findLargest(a, n);
swap(&i, &j);
selectionSort(a, n - 1);
}
int *findLargest(int *a, int n)
{
int *p;
int *p_max = a;
for(p = a + 1; p < a + n - 1; p++) {
if ( *p > *p_max)
p_max = p;
}
return p_max;
}
void swap(int *p, int *q)
{
int temp = *(p-1);
*(p-1) = *q;
*q = temp;
}
The problem is in your call of swap: you swap the content of two local variables
int i;
int j;
... // Some other code, then
swap(&i, &j);
This has no effect on the original array. You should be passing p+n-1 and findLargest(a, n) directly, or store their results in pointers, not in ints:
swap(p+n-1, findLargest(a, n));
In addition, your swap is broken: rather than swapping the content of two pointers, it assumes that p points one element past the target location. This is a bad assumption to make in a general-purpose function, such as swap, and it also leads to undefined behavior in your program.
void swap(int *p, int *q) {
int temp = *p;
*p = *q;
*q = temp;
}

Nothing works - references, pointers

void load(int *n, int *x, int **arr)
{
arr = (int**)malloc(sizeof(int*)*(*n));
for(int i = *n; i >= 0; i--)
{
scanf("%d", &arr[i]);
}
}
int main()
{
int n = 0, x = 0;
int *arr;
load(&n, &x, &arr);
printf("%d", arr[1]);
return EXIT_SUCCESS;
}
The program compiles properly, but it throws windows error during the printf() in main function. Displaying just "arr" gives random big numbers. What is wrong here?
arr = (int**)malloc(sizeof(int*)*(*n));
doesn't change anything in main, it only overwrites the copy of the pointer (address of arr in main) that load receives.
What the function should do is change arr in main, for that, you have to dereference the argument,
*arr = (int*)malloc(sizeof(int)*(*n)); // cast for C++ compiler left in
to change the value of arr in main. (The object that the argument arr of load points to, that is arr in main, needs to be changed, hence you need to modify *arr in load.)
The scans should then be
scanf("%d", &(*arr)[i]);
or (equivalent)
scanf("%d", *arr + i);
#include <stdio.h>
#include <stdlib.h>
void load(int *n, int *x, int **arr)
{
int i = 0;
*arr = (int*) malloc(*n * sizeof(int));
if(!*arr) {
perror("Can not allocate memory!");
return;
}
for(i = *n; i >= 0; i--)
{
scanf("%d", *arr + i);
}
return;
}
int main()
{
int n = 0, x = 0;
int *arr;
int i;
/* You probably need to initialize n */
n = 5;
load(&n, &x, &arr);
for(i = n; i >= 0; i--)
{
printf("%d - %d\n", i, arr[i]);
}
return EXIT_SUCCESS;
}

Resources