static keyword not working in C (Visual Studio) - c

Question -
N numbers are entered by the user (N is also given by the user). Store the numbers in
an array. Write a C function which deletes all the second largest elements and
rearranges the array. The program should appropriately print the new array and the
value of N. For e.g if N=7 and the elements are 7 11 13 11 8 7 4 the output should be
N=5 and the array is 7 13 8 7 4
My Code -
#include<stdio.h>
int secondLargest(int arr[], int n);
int indexOfSecondLargest(int arr[], int n, int max2);
void deleteElement(int arr[], int n, int index);
void deleteSecondLargest(int arr[], int n);
void printArray(int arr[], int n);
int main()
{
static int n;
printf("Enter value of n \n");
scanf("%d", &n);
int arr[100];
printf("Enter n numbers \n");
for (int i = 0; i < n; i++)
{
scanf("%d", &arr[i]);
}
deleteSecondLargest(arr, n);
printf("New value of n = %d and the array is \n", n);
printArray(arr, n);
return 0;
}
int secondLargest(int arr[], int n)
{
int max1 = arr[0], max2 = arr[0];
for (int i = 0; i < n; i++)
{
if (arr[i] > max1)
{
max2 = max1;
max1 = arr[i];
}
if (arr[i] > max2 && arr[i] < max1)
{
max2 = arr[i];
}
}
return max2;
}
int indexOfSecondLargest(int arr[], int n, int max2)
{
for (int i = 0; i < n; i++)
{
if (arr[i] == max2)
{
return i;
}
}
return -1;
}
void deleteElement(int arr[], int n, int index)
{
for (int i = index; i < n - 1; i++)
{
arr[i] = arr[i+1];
}
n = n - 1;
}
void deleteSecondLargest(int arr[], int n)
{
int max2 = secondLargest(arr, n);
int index = indexOfSecondLargest(arr, n, max2);
while (index != -1)
{
deleteElement(arr, n, index);
index = indexOfSecondLargest(arr, n, max2);
}
}
void printArray(int arr[], int n)
{
for (int i = 0; i < n; i++)
{
printf("%d ", arr[i]);
}
}
My Output -
Enter value of n
7
Enter n numbers
7 11 13 11 8 7 4
New value of n = 7 and the array is
7 13 8 7 4 4 4
Even though I am using static keyword before int n, the value of n is not getting updated to 5 in main() function. I even tried putting int n as a global variable but still it doesn't work.
Can someone help me ??

Adding static to int n; says “This n persists through all of program execution.” it does not say “This n is the only n in the whole program.” Where a parameter n is declared, as in void deleteElement(int arr[], int n, int index), that creates an n different from the n in main.
However, even if no parameter is declared with the name n, an n declared inside main is not visible in any other function. To use the same n throughout the program, you need to declare int n; or static int n; outside of any function, anywhere before the first function that uses n, and you need to not declare any other n.
That would likely solve this problem for you. However, it is bad practice to use external identifiers for objects. Instead, you should use int n; in main and modify deleteElement so that it provides main with the updated value. It could do this by returning an int instead of void, or you could modify deleteElement to take a pointer to an int instead of taking an int, by making the parameter int *n. Then you would have to use it inside the function as *n instead of n.

Related

How do I create a function to change values ​in an array?

Write a function int set_array(int *v, int i, int j, int k) that sets the elements i to j to a specific value k among the elements of the int array v of size n (<= 100). This is the given problem.
When I input 10 0 9 -1, to set all the elements it comes out normally as -1.
However, when 5 2 2 0 is input, to set only element [2], all output values ​​come out as 0.
I am using eclipse and no error came out. Which part is wrong?
#include <stdio.h>
int set_array(int* v, int i, int j, int k)
{
int t;
for (t = i; t <= j; t++)
{
v[t] = k;
}
return 0;
}
int main()
{
int t;
int size, value;
int start, end;
scanf("%d %d %d %d", &size, &start, &end, &value);
int array[size];
for (t = 0; t < size; t++)
{
scanf("%d", &array[t]);
}
set_array(array, start, end, value);
for (t = 0; t < size; t++)
{
printf("%d\n", array[t]);
}
return 0;
}
The initialization of the array is incorrect.
In scanf and printf the i should be replaced by the letter t.
You are mixing t and i as the for loops indexes:
for (t = 0; t < n; t++)
{
scanf("%d", &ary[i]);
}
In this case you only scan i position, not the t running the for loop
Be careful using many one letters variables...

Trying to write a program to fill an array with random numbers in C

My issue is that I am getting segmentation fault (core dumped) each time I try, I have yet to clean up my code, but I am stumped.
I must enter the values in with the compiler e.g "./filename 0 100" whereby 0 is min and 100 is max.
It must then fill the array of 10 elements with random numbers (0-100). I am so close, just can't fathom the main function.
Also, how can I print the array {0,1,2,3} in format "[0,1,2,3]" including the commas, without it looking like "[0,1,2,3, ]"
#include <stdlib.h>
#include <stdio.h>
int getRandom(int min, int max);
void fillArray(int data[], int size, int min, int max);
void printArray(int data[], int size);
int main(int argc, char *argv[]) {
int a;
int b;
if (argc>=3){
a = atoi(argv[1]);
b = atoi(argv[2]);
int arr[10];
printf("\t An array with random values from 0 to 100 \n");
fillArray(arr,10 ,a, b);
printArray(arr, 10);
} else {
printf("Incorrect number of arguments - please call with assignment min max\n");
}
return 0;
}
int getRandom(int min, int max) {
int result = 0;
int low = 0;
int high = 0;
if (min<max) {
low = min;
high = max+1;
} else {
low = max + 1;
high = min;
}
result = (rand() % (high-low)) + low;
return result;
}
void fillArray(int data[], int size, int min, int max){
int i;
for(i=min ; i < max+1; i++){
data[i] = getRandom(min,max);
}
}
void printArray(int data[], int size){
int i;
printf("[");
for(i=0; i<size; i++){
printf("%d,", data[i]);
}
printf("]");
}
I agree with #Steve Friedl that the main problem with your program lies in the fillArray function. There i should run from 0 to size.
As for your second question, testing whether you're printing the last number helps to suppress the unwanted comma:
void printArray(int data[], int size) {
printf("[");
for (int i = 0; i < size; i++) {
printf("%d", data[i]);
if (i < size - 1)
printf(",");
}
printf("]");
}
If you prefer a more compact solution (although with an optimizing compiler there's not really a difference), you could write it as:
void printArray(int data[], int size) {
printf("[");
for (int i = 0; i < size; i++) {
printf("%d%c", data[i], i < size-1 ? ',' : ']');
}
}
Also, in your main function, you should include a and b in your printing:
printf("\t An array with random values from %d to %d \n", a, b);
I believe this is blowing things up for you:
void fillArray(int data[], int size, int min, int max){
int i;
for(i=min ; i < max+1; i++){ // <-- HERE
data[i] = getRandom(min,max);
}
}
The calling function allocates 10 items in the arr array, and that's passed as the size parameter, but you're not using that parameter to limit filling up the array. If the max value is 100, then it's trying to fill one hundred slots instead of just ten.
for (i = 0; i < size; i++)
data[i] = getRandom(min,max);
should fix at least this issue.
EDIT: The comma thing, I prefer to add commas before the items unless this is the first. In this case it doesn't matter much, but it's more general, especially for variable-length lists where you don't know you're at the end until you get there. Augmenting the helpful response from #JohanC :
void printArray(int data[], int size) {
printf("[");
for (int i = 0; i < size; i++) {
if (i > 0) printf(",");
printf("%d", data[i]);
}
printf("]");
}

Array same element in C

c finding the array of the same element
A function called rLookupAr() takes in three parameters, array, size and target, and returns the subscript of the last appearance of a number in the array. The parameter size indicates the size of the array. For example, if array is {2,1,3,2,4} and target is 3, it will return 2. With the same array, if target is 2, it will return 3. If the required number is not in the array, the function will return –1. The function prototype is given below.
int rLookupAr(int array[], int size, int target);
Write a C program to test the function.
A sample input and output session is given below:
Enter array size: 5 Enter 5 numbers: 2 1 3 2 4 Enter the target number: 2 rLookupAr() = 3
Enter array size: 5 Enter 5 numbers: 2 1 3 2 4 Enter the target number: 5 rLookupAr() = -1
This is my code
#include <stdio.h>
int rLookupAr(int array[], int size, int target);
int main() {
int numArray[80];
int target, i, size;
printf("Enter array size: ");
scanf("%d", &size);
printf("Enter %d numbers: ", size);
for (i = 0; i < size; i++)
scanf("%d", &numArray[i]);
printf("Enter the target number: ");
scanf("%d", &target);
printf("rLoopupAr(): %d", rLookupAr(numArray, size, target));
return 0;
}
int rLookupAr(int array[], int size, int target) {
int j,i;
for (j = 0; j < size; j++)
if(array[i] == target)
return j;
return -1;
}
I do not know how to implement when same array elements numbers are the same as bolded
You can code it looping through the array in reverse way like
int rLookupAr(int array[], int size, int target) {
int j;
for (j = size-1; j >= 0; j--)
if (array[j] == target)
return j;
return -1;
}
Or looping through the whole and store the value in a lookup variable
int rLookupAr(int array[], int size, int target) {
int j;
char found = -1;
for (j = 0; j < size; j++)
if (array[j] == target)
found = j;
return found;
}

Sort elements in array C [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I am trying to create a program that will sort elements in 4 steps (read elements - print elements - sort them - print the sorted version).
I need help with the sorting (third) part.
Here is my code:
/*
* A simple program to sort numbers in correct order
*/
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 10
#define SENTINEL -99
int main()
{
int tableFill(int a[], int max);
void tableInsert(int a[], int num, int val);
void tableSort(int a, int n);
void tablePrint(int a, int n);
int num;
int table[MAXSIZE];
int max;
num=tableFill(table,MAXSIZE);
return EXIT_SUCCESS;
}
int tableFill(int a[], int max)
{
int r; // input from scanf
int next; // score from user
int cnt = 0;
printf("Enter the numbers! \n");
while ((r=scanf("%i", &next))!= EOF && cnt<max)
{
if (r == 0) //invalid input data
{
printf("Nonnumeric data entered. Please enter a number. \n");
while (getchar()!= '\n'); // flush invalid data
}
else
a[cnt++]=next;
}
if(r==1) //another value was read but the array is full
printf("Error - too many values. Array size %i.\n", max);
}
void tableInsert (int a[], int num, int val)
{
int pos;
for(pos = num; pos>0 && val<a [pos-1]; pos--)
a [pos] = a [pos -1];
a[pos] = val;
}
void tableSort(int a, int n)
{
}
void tablePrint(int a, int n)
{
int i;
for(i = n -1; i>=0; i++)
{
printf("%i\n",a[i]);
}
}
SOLUTION
I used David C. Rankin's solution and fixed my code. This is my final version:
/*
* A simple program to sort numbers in the correct order
*/
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 10 //max elements in array
int main () {
int tableFill (int a[], int max);
void tableSort (int a[], int n);
void tablePrint (const a[], int n);
int arr[MAXSIZE]; //creating an array
int n = tableFill (arr, MAXSIZE); //declaring variable to work with array
tablePrint (arr, n); //prints unsorted values
printf ("Here is your sorted array:\n");
tableSort (arr, n); // sorts values in order
tablePrint (arr, n); // prints sorted values
return 0;
}
// read values from stdin into array up to 'max' values
int tableFill(int a[], int max) {
int r; // input from scanf
int next; // score from user
int cnt = 0; // loop variable
printf("Enter the numbers! \n");
while ((r=scanf("%i", &next))!= EOF && cnt<max)
{
if (r == 0) //invalid input data
{
printf("Nonnumeric data entered. Please enter a number. \n");
while (getchar()!= '\n'); // flush invalid data
}
else
a[cnt++]=next;
}
if(r==1) //another value was read but the array is full
printf("Error - too many values. Array size %i.\n", max);
return cnt;
}
// swap values at array indexes 'i' and 'j'.
void tableSwap (int a[], int i, int min_index)
{
int tmp = a[i];
a[i] = a[min_index];
a[min_index] = tmp;
}
//sort array
void tableSort (int a[], int n)
{
void tableSwap (int a[], int i, int min_index);
int i, j; //loop counters
int min, min_index; //adjusting variables for loops
for (i = 0; i <= n - 2; i++) {
min = a[i];
min_index = i;
for (j = i + 1; j <= n - 1; j++) {
if (a[j] < min){
min = a[j];
min_index = j;
}
}
tableSwap (a, i, min_index);
}
}
//print all elements in array.
void tablePrint (const a[], int n)
{
int i; //variable for print
for (i = 0; i < n; i++)
printf ("%d ", a[i]);
printf ("\n");
}
As pointed out in the comments, qsort is the defacto standard sort routine contained in the C standard library. It is incredibly flexible and incredibly fast due to using a combination of sorting methods optimized for the range of data being sorted. Beginning C users generally have difficulty writing the compare functions because it involves the use of pointers. Just take the time needed to write a few compare functions are get comfortable with it -- it will save you a lot of grief in the long run.
That said, before looking at both alternative sorts, C-style generally uses lower-case for variable and function names. Leave camelCase names for C++. See e.g. NASA - C Style Guide, 1994
Sorting with the old-slow bubblesort. For sorting anything with greater than 100 elements, the efficiency of the bubblesort craters. It is hundreds of times slower than qsort for any large number of element. That being said, putting a bubblesort together that incorporates your tableswap requirement is straightforward:
/** sort array using slow old bubblesort */
void tablebubblesort (int *a, int n)
{
int i, j;
for (i = 0; i < n - 1; i++) {
for (j = 0; j < n - i - 1; j++) {
if (a[j] > a[j + 1]) /* For decreasing order use < */
tableswap (a, n, j, j+1);
}
}
}
Your tableswap function will look similar to:
/** swap values at array indexes 'i' and 'j'. */
void tableswap (int *a, int n, int i, int j)
{
if (i >= n || j >= n) return;
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
Simply call the function in your code with tablebubblesort (arr, n);
qsort is even simpler. The full function (you really don't need a separate function) is:
/** qsort the array */
void tablesort (int *a, int n, size_t sz)
{
qsort (a, n, sz, compare);
}
It requires a compare function which is simply:
/** qsort compare function */
int compare (const void *a, const void *b)
{
return (*(int *)a - *(int *)b);
}
Don't let you eyes roll over in your head simply because you see const void *a, etc.. it is really straight forward. Your a and b pointers represent a pointer to individual integers in the array (e.g if say a[1] = 5, the pointer is just &a[1] the address of the element). So taking the compare function apart, knowing you are just passing the address of an element (e.g. integer pointers) to compare, you would write it long-hand as follows:
int compare (const void *a, const void *b)
{
int *value1 = (int *)a; /* cast each to int pointer */
int *value2 = (int *)b;
if (*value1 > *value2) /* compare dereferenced values */
return 1;
if (*value1 < *value2)
return -1;
return 0;
}
Or, if it makes you happier, you can cast and dereference all at once and then just operate on integer values:
int compare (const void *a, const void *b)
{
int value1 = *(int *)a;
int value2 = *(int *)b;
if (value1 > value2)
return 1;
if (value1 < value2)
return -1;
return 0;
}
Either way it is the same. (arguably, the first is the most proper because it avoid the "appearance" of type punning pointers and derefencing void values, but that is for another day) There is no magic, just do it enough times for integers, strings, structs, etc.. until it sinks in. It's more than worth the time.
Putting the rest of the pieces together, you could meet your requirements with something similar to the following:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXI 128
int tablefill (int *a, int max);
void tableinsert (int *a, int *n, int max, int num, int val);
void tableswap (int *a, int n, int i, int j);
void tablesort (int *a, int n, size_t sz);
void tablebubblesort (int *a, int n);
void tableprint (int *a, int n);
int compare (const void *a, const void *b);
int main (void) {
int arr[MAXI] = {0};
int n = 0;
printf ("enter array values ([ctrl+d] to end)\n");
n = tablefill (arr, MAXI);
tableprint (arr, n);
printf ("\ninsert '5' as the '2nd' element of array\n");
tableinsert (arr, &n, MAXI, 2, 5);
tableprint (arr, n);
printf ("\nswap indexes '1' and '3'\n");
tableswap (arr, n, 1, 3);
tableprint (arr, n);
printf ("\nsorted array\n");
#ifdef WQSORT
tablesort (arr, n, sizeof *arr); /* gcc -DWQSORT to use tablesort */
#else
tablebubblesort (arr, n);
#endif
tableprint (arr, n);
return 0;
}
/** read values from stdin into array up to 'max' values. */
int tablefill (int *a, int max)
{
int idx = 0, tmp;
while (idx + 1 < max && scanf ("%d", &tmp) == 1)
a[idx++] = tmp;
return idx;
}
/** insert 'val' as the 'num' element in 'a' ('num - 1' index),
* update 'n' to current number of elements.
*/
void tableinsert (int *a, int *n, int max, int num, int val)
{
if (num >= max || *n + 1 == max) return;
if (num >= *n) { a[num] = val; (*n)++; return; }
int i;
for (i = *n; i >= num; i--)
a[i] = a[i-1];
a[i] = val;
(*n)++;
}
/** swap values at array indexes 'i' and 'j'. */
void tableswap (int *a, int n, int i, int j)
{
if (i >= n || j >= n) return;
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
/** qsort the array */
void tablesort (int *a, int n, size_t sz)
{
qsort (a, n, sz, compare);
}
/** sort array using slow old bubblesort */
void tablebubblesort (int *a, int n)
{
int i, j;
for (i = 0; i < n - 1; i++) {
for (j = 0; j < n - i - 1; j++) {
if (a[j] > a[j + 1]) /* For decreasing order use < */
tableswap (a, n, j, j+1);
}
}
}
/** print all elements in array. */
void tableprint (int *a, int n)
{
if (!a) return;
int i;
for (i = 0; i < n; i++)
printf (" a[%2d] : %d\n", i, a[i]);
}
/** qsort compare function */
int compare (const void *a, const void *b)
{
return (*(int *)a - *(int *)b);
}
The code contains both the bubblesort and qsort version of the sort. You simply pass the define -DWQSORT to compile with the qsort code or compile without it for the bubblesort. e.g.
Compile Both Versions
$ gcc -Wall -Wextra -Ofast -o bin/array_fill array_fill.c
$ gcc -Wall -Wextra -Ofast -DWQSORT -o bin/array_fill_qsort array_fill.c
Example Use/Output
$ echo "1 4 2 3" | ./bin/array_fill
enter array values ([ctrl+d] to end)
a[ 0] : 1
a[ 1] : 4
a[ 2] : 2
a[ 3] : 3
insert '5' as the '2nd' element of array
a[ 0] : 1
a[ 1] : 5
a[ 2] : 4
a[ 3] : 2
a[ 4] : 3
swap indexes '1' and '3'
a[ 0] : 1
a[ 1] : 2
a[ 2] : 4
a[ 3] : 5
a[ 4] : 3
sorted array
a[ 0] : 1
a[ 1] : 2
a[ 2] : 3
a[ 3] : 4
a[ 4] : 5
$ echo "1 4 2 3" | ./bin/array_fill_qsort
<same outoput>
Look over all the code and let me know if you have questions. This is basic meat and potatoes C and you need to make sure you understand each line, and each character in each line. Take it slow.
Regarding
int tableFill(int a[], int max);
void tableInsert(int a[], int num, int val);
void tableSort(int a, int n);
void tablePrint(int a, int n);
You're declaring the prototypes inside main which is not usually done. They are usually declared in global scope so that they stay put till the end.
Regarding
int tableFill(int a[], int max)
You're not returning anything. Since you're dealing with the pointers you could change int to void.
Regarding
void tableInsert (int a[], int num, int val)
Ask yourself from where you are calling this function.
Regarding
void tableSort(int a, int n)
{
}
See this guide which explains sorts.
Regarding :
void tablePrint(int a, int n)
{
int i;
for(i = n -1; i>=0; i++)
{
printf("%i\n",a[i]);
}
}
Since you're printing an array,so one parameter to this function should be an array.

Change position of an exact number of elements in an array

Let's say we have an array of m elements and we want to change randomly the position of exactly n of them, where of course 2 <= n <= m.
For example: if we have this array of 10 ints {1 2 3 4 5 6 7 8 9 10} and we ask for 4 of its elements to change positions randomly, a result could be {3 2 1 4 5 6 10 8 9 7}
What is the simplest way to program this in ANSI C? (pseudocode will also be just fine)
Step1). Generate a list of n random unique numbers between 1 and m. This list should NOT be sorted. Eg, for your example, the list could have been [10,7,1,3]
Step 2) do something like :
int save = array[list[0]];
For (i=0; i<n-1; i++) {
Array[list[i]] = array[list[i+1]];
}
Array[list[n-1]] = save;
Edit: actually, you'll have to have subtract 1 from each list[whatever] to allow for zero-based arrays - but I'm sure you get the idea :)
since at least two numbers must be swapped, i would pick two random numbers from array first and then swap them. they are added to array that holds swapped indexes. if there's more to swap, pick another number different than swapped ones and swap it with one of the previously swapped numbers.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void print_arr(int a[], int size) {
int i;
for (i = 0; i < size; i++) {
printf("%d ",a[i]);
}
printf("\n");
}
void swap(int a[], int i, int j) {
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
int next_idx(int swapped[], int s_count, int size) {
int n, i;
char in_arr;
while (1) {
in_arr = 0;
n = rand() % size;
for (i = 0; i < s_count; i++) {
if (swapped[i] == n) {
in_arr = 1;
break;
}
}
if (!in_arr) {
break;
}
}
return n;
}
void swap2_or_more(int a[], int size,int count) {
srand(time(NULL));
int i, j, s_count = 0;
int swapped[size];
i = rand() % size;
swapped[s_count] = i;
s_count++;
do {
j = rand() % size;
} while (i == j); // make sure indexes are different
swapped[s_count] = j;
s_count++;
swap(a, i, j);
count -= 2;
while (count) {
i = next_idx(swapped, s_count, size);
j = rand() % s_count;
swap(a, i, swapped[j]);
swapped[s_count] = i;
s_count++;
count--;
}
printf("swapped indexes:\n");
print_arr(swapped, s_count);
}
int main(void)
{
int a[] = {1,2,3,4,5,6,7,8,9,10};
swap2_or_more(a, 10, 5);
printf("array after swap:\n");
print_arr(a, 10);
return 0;
}

Resources