Passing an array to function a looping through it in C - arrays

I know I'm asking pretty basic question here, but could anyone give me a hint how to properly loop through an array which is initialized in another function ? I tried googling, found tons of videos but I didn't manage to get it right just yet. Would anyone please help me find out, what I'm missing in my code ? I'm a struggling beginner. Thanks in advance for your time.
My code (not functioning):
#include <stdio.h>
#define ARR_RANGE 1000000
#define GREATEST_NUMBER 1000000
void sieve(int eratosthenes[]);
int main()
{
int eratosthenes[ARR_RANGE];
int n = 999;
int c;
for(i = 2; i <= arrLen; ++i)
{
if(eratosthenes[i]!= -1)
{
int c = 0;
while(n % i == 0)
{
n /= i;
++c;
}
if(c >= 2)
{
printf("%d^%d x ", i, c);
}
else if(c == 1)
{
printf("%d x ", i);
}
}
else
continue;
}
return 0;
}
void sieve(int eratosthenes[])
{
for(int i = 1; i < GREATEST_NUMBER; ++i)
{
eratosthenes[i] = i;
}
for(int i = 2; i*i < GREATEST_NUMBER; ++i)
{
if(eratosthenes[i] != -1)
{
for(int j = 2*i; j < GREATEST_NUMBER ; j += i)
eratosthenes[j] = -1;
}
}
int arrLen = sizeof eratosthenes / sizeof eratosthenes[0];
}

In the main is not visible the call of function sieve,so the array is not passed into function, to do this you have to write in the main sieve(eratosthenes); (Passage by reference)

Related

Why I can't assign a function return to a matrix element?

Ok, so I need to input a matrix of n elements and to replace each composite number with the closest prime number. I made functions for reading the matrix, showing the matrix, finding if a number is prime or not and finding the closest prime number to a number and they work.
Here is what I did and the problem is that the replacement does not work and I get the error: Process terminated with status -1073741510 (0 minute(s), 18 second(s))
#include <stdio.h>
#include <stdlib.h>
int n;
int readMatrix(int **matrix)
{
for (int i=0; i<n; i++) {
for (int j=0; j<n; j++) {
printf("matrix[%d][%d]=", i, j);
scanf("%d", &matrix[i][j]);
}
}
return matrix;
}
void showMatrix(int **matrix)
{
for (int i=0; i<n; i++) {
for (int j=0; j<n; j++) {
printf("%d ", matrix[i][j]);
}
printf("\n");
}
}
int prime(int a)
{
int c = 0;
for (int i=1; i<a; i++) {
if (a % i == 0) {
c++;
}
}
if (c == 1) {
return 1;
} else return 0;
}
int nearPrime(int b)
{
int lp, bp, ok = 0, p;
lp = b - 1;
bp = b + 1;
while (ok != 1) {
if (prime(lp) == 1) {
ok = 1; break;
}
lp--;
}
ok = 0;
while (ok != 1) {
if (prime(bp) == 1) {
ok = 1; break;
}
bp++;
}
if ((b-lp) < (bp-b)) {
p = lp;
} else p = bp;
return p;
}
int main()
{
int **matrix, aux;
printf("n=");
scanf("%d", &n);
matrix = malloc(n*sizeof(int *));
if (matrix == NULL) exit(1);
for (int i=0; i<n; i++) {
matrix[i] = malloc(n*sizeof(int));
if (matrix[i] == NULL) exit(1);
}
readMatrix(matrix);
showMatrix(matrix);
for (int i=0; i<n; i++) {
for (int j=0; j<n; j++) {
if (prime(matrix[i][j]) == 0 && matrix[i][j] != 1) {
matrix[i][j] = nearPrime(matrix[i][j]);
}
}
}
showMatrix(matrix);
for (int i=0; i<n; i++) free(matrix[i]);
free(matrix);
return 0;
}
Can you tell me why it is not working?
UPDATE
I think I solved it. When checking if a matrix number is prime I also added the condition that it needs to be different than 1 because the program will return 0 when checking if 1 is prime number and it needs to return 1 since 1 is actually a prime number.
Thanks for all the tips!
I think I may have found the issue in your code. The problem lies in your nearPrime function. It will work for most numbers that it takes in as an argument but that is not the case if you input the number 1 for this function. Consider what will happen if it does take in the number 1.
Then, your variable lp = (1 - 1) = 0. When you then further input this into the prime function, it will not return 1 because of the way it is implemented. You then keep on decreasing this number if no prime is found and since the number is now negative, it will never even enter in the for loop in the prime function and the prime function will then always return 0. Thus, you will get stuck in the while(ok != 1) loop for a really long time and that is why your process terminates. To fix this, make sure you check that lp != 0 before proceeding to enter the loop. Since you are also checking for the nearest prime, you also need to check if lp is 0 before returning a value. In short, make the following change to your code.
int nearPrime(int b)
{
int lp, bp, ok = 0, p;
lp = b - 1;
bp = b + 1;
if (lp != 0)
{
while (ok != 1) {
if (prime(lp) == 1) {
ok = 1; break;
}
lp--;
}
}
ok = 0;
while (ok != 1) {
if (prime(bp) == 1) {
ok = 1; break;
}
bp++;
}
if (((b - lp) < (bp - b)) && lp != 0) {
p = lp;
}
else p = bp;
return p;
}
One other thing: your readMatrix function seems to expect a return type of int but you are returning the argument matrix, which is of type int**. Furthermore, in your main code, you are not actually doing anything with your returned value so probably change the return type of your readMatrix function to void (and don't return matrix, of course).

program to know all the huiwen number doesn't work well

this program is build to know all the huiwen number from 1 to 256
like 11^2=121 so 11 is a huiwen.
actually I have a good one
but I am confuse about why this program doesn't work well.
#include<stdio.h>
int is_huiwen(int l)
{
//DON'T WORK?WHY?
int number[20]={0};
int i,j,k;
int f=l*l;
for(j=0;f;j++)
{
number[j]=f%10;
f/=10;
}
for(k=0;j-k>0;k++,j--)
{
if(number[j]!=number[k] )
{
return 0;
}
}
return 1;
/* this is ok
int y=0;
int t = l*l;
int x = t;
do
{
y=y*10+t%10;
t /= 10;
}
while(t);
if(x==y)
return 1;
else
return 0;
*/
}
int main()
{
int i;
int flag;
for(i=0;i<256;i++)
{
flag=is_huiwen(i);
if(flag)
{
printf("%d is huiwen",i);
}
else
{
printf("\n");
}
}
printf("end\n\n\n\n");
return 0;
}
end.
The error is the if( number[j] != number[k] )line as pointed out by BluePixy.
The correction is if( number[j-1] != number[k] )
I would to point out that the code has hidden the problem partly because of a smattering of one letter variable names and inconsistent naming.
Here is the code that I used to find the same solution
int is_huiwen_2(int L )
{
int ret = 1;
int j = 0;
int k = 0;
int t = L * L;
int number[8] = { 0 };
for( j = 0; t; j++)
{
number[j] = t % 10;
t /= 10;
}
for( k = 0; (j - k) > 0 && ret; k++, j-- )
{
if( number[j-1] != number[k] )
{
ret = 0;
}
}
return( ret );
}
int is_huiwen_1( int L )
{
int ret = 1;
int y = 0;
int t = L * L;
int x = t;
do
{
y = y * 10 + t % 10;
t /= 10;
}
while( t );
if( x != y )
{
ret = 0;
}
return( ret );
}
int main()
{
int i = 0;
int flag = 0;
for( i = 0; i < 256; i++)
{
flag = is_huiwen_1(i);
if(flag)
{
printf("1: %d is huiwen\n",i);
}
}
for( i = 0; i < 256; i++)
{
flag = is_huiwen_2(i);
if(flag)
{
printf("2: %d is huiwen\n",i);
}
}
printf("end\n");
return( 0 );
}
I don't know what all the variables do. The use of 'l' looks like a '1' in some editors.
Being a Code Refactoring monk or zealot, I did some modifications such as reducing the code to one consistent return condition, value and point of return.
While it might seem overly simple, having multiple declarations on one line hides trouble, such as int i not being used in the second function.
The use of int numbers[20] = { 0 }; was also misleading us as for the range of values here [20] was overkill, having an explanation of what the range of values "12321", "1234321" where could have meant easier debugging of this code. A simple comment of what the outcome should look like would have solved several problems.
// A Huiwen number looks like this "12321", "1589851"
While this might be a simple exercise it portends greater problems down the line if this was not a trivial exercise. Try not to make it hard on the next coder.
Document your algorithms, arithmetic and variables please.

C Program will compile and run in Linux but not Windows

I'm working on an assignment for a programming class and am having an issue with a program. The goal is to take in a set of user defined values, store them in an array, then find the closest pair of numbers (the numbers with the smallest difference). The numbers don't have to have consecutive indices. Also, the array size of 50 is defined in the assignment by the professor.
The problem I'm running into is that the program will compile in both Linux (Ubuntu 14.xx) and Windows 10, however, when I run the result in Linux, it works fine but in Windows it outputs nothing.
This is the first time I've had this issue and as far as I know I didn't use any system specific commands. Any help provided would be appreciated.
Code:
#include <stdio.h>
int main()
{
int i, j, a, b, temp, mindiff, count;
int numarray[50];
count = 0;
for (i = 0; i < 50; i++)
{
scanf("%d", &numarray[i]);
count++;
if (numarray[i] == -1)
{
numarray[i] = 0;
count--;
break;
}
}
mindiff = 100;
for (i = 0; i < count; i++)
{
for (j = 0; j < count; j++)
{
a = numarray[i];
b = numarray[j];
if (a != b)
if (a > b)
temp = a - b;
else
temp = b - a;
if (temp < mindiff)
mindiff = temp;
}
}
for (i = 0; i < count; i++)
{
for (j = 0; j < count; j++)
{
a = numarray[i];
b = numarray[j];
if (a != b)
{
if (a > b && (a - b) == mindiff)
{
printf("Closest pair: %d and %d, Difference: %d\n", a, b, mindiff);
return 0;
}
}
}
}
return 0;
}
There are at least two major problems:
Your code has undefined behavior because you use temp even if it has not been set (you should start a block after if (a != b)). undefined behavior means anything can happen, including apparent success on Linux and failure on Windows.
You initialize mindiff to 100. If all numbers are farther apart from each other, mindiff will not be changed and the second loop will not print anything.
Here is a simpler version:
#include <stdio.h>
int main(void) {
int count, i, j, mina, minb, mindiff;
int numarray[50];
for (count = 0; count < 50; count++) {
if (scanf("%d", &numarray[count]) != 1 || numarray[count] == -1)
break;
}
mindiff = mina = minb = 0;
for (i = 0; i < count; i++) {
for (j = 0; j < count; j++) {
int a = numarray[i];
int b = numarray[j];
if (a > b) {
int diff = a - b;
if (mindiff == 0 || mindiff > diff) {
mindiff = diff;
mina = a;
minb = b;
}
}
}
}
if (mindiff == 0) {
if (count == 0) {
printf("No numbers input\n");
} else {
printf("The numbers are all identical\n");
}
} else {
printf("Closest pair: %d and %d, Difference: %d\n",
mina, minb, mindiff);
}
return 0;
}
You have the following problem:
Note: temp is considered a stack variable under the main function and since you do not initialize it, it becomes garbarge (for example a large negative number):
int i, j, a, b, temp, mindiff, count;
Then if temp is a large negative number, mindiff = the garbarge value of mindiff,
if (temp < mindiff)
mindiff = temp;
And the following if statement is always false.
if (a > b && (a - b) == mindiff)
And nothing gets printed.

Perfect Number Check

So the idea behind my code is to create a program that uses functions to check and print all perfect numbers between 1 and 1000. I've come up with this, but the issue is that nothing prints. It builds successfully, runs, and exits.
I've gone through my code 3-4 times and I can't find the gap in logic, so I'm thinking its a variable definition issue, something to do with how in-scope certain functions are. Would anyone have any input for why my program is failing to recognize a perfect number, and then print it?
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
/*
*
*/
void perfectNumCheck(int num);
void perfectNumPrint (int perfectNum);
int main(void) {
int i;
for (i = 1; 1 <= 1000; i++)
perfectNumCheck(i);
}
void perfectNumCheck(int num) {
int i;
int temp = 0;
for (i = 0; i < num; i++) {
if (num % i == 0)
temp += i;
}
if (temp == num)
perfectNumPrint(num);
}
void perfectNumPrint(int perfectNum) {
int i;
for (i = 0; i < perfectNum; i++)
if (perfectNum % i == 0)
printf ("%d, ", i);
printf("are factors of the perfect number %d.\n", perfectNum);
}
You have a typo here:
for (i = 1; 1 <= 1000; i++)
perfectNumCheck(i);
Should be
for (i = 1; i <= 1000; i++)
perfectNumCheck(i);
Also, you're dividing by zero. Change all your i = 0 in your for loops to i = 1
boolean perfectNum(int currentNum) {
int i, sum = 0;
for (i = 1; i < currentNum; i++)
if (perfectNum % i == 0)
sum += i;
if(sum == currentNum) return ture;
return false;
}
Perfect Number Test : If the sum of all factors are equals to number itself.
public static bool IsItPerfectNumber(int input)
{
bool IsPerfectNumber = false;
//Validation and Find all Factore
List<int> myList = FindFactors(input);
//Sum if factor
int sumOfFactor = SumFactor(myList);
//Check Is Perfact Number
if (sumOfFactor == input)
{
IsPerfectNumber = true;
}
return IsPerfectNumber;
}
public static List<int> FindFactors(int input)
{
List<int> myList = new List<int>();
for (int j = 1; j < input; j++)
{
if (input % j == 0) {
myList.Add(j);
}
}
return myList;
}
public static int SumFactor(List<int> myList)
{
return myList.Sum();
}
Try this:
boolean perfectNum(int currentNum) {
int i, sum = 0;
for (i = 1; i < currentNum; i++)
if (perfectNum % i == 0)
sum += i;
if(sum == currentNum) return ture;
return false;
}

How come my straight counter remains at a value of zero?

I am making a program in the C90 standard using GCC in Ubuntu 10.04, that randomly generates a hand of 5 card structs and calculates if the hand is a flush, straight, etc.
My function to calculate straights is:
int isStraight(card hand[]) {
int i, count = 1, result = 0;
for (i = 0; i < HAND_SIZE-1; i++) {
if (hand[i].pips == ((hand[i+1].pips) + 1)) {
count++;
}
}
if (count == HAND_SIZE)
result = 1;
return result;
}
My main function:
int main(void) {
int i, j;
int numHands = 0;
int flushCount = 0;
int straightCount = 0;
int xOfAKindCount = 0;
int straightFlushCount = 0;
int fullHouseCount = 0;
int isTwoPairCount = 0;
card deck[DECKSZ] = {0};
card hand[HAND_SIZE] = {0};
stack deckStack = {0};
stack handStack = {0};
initDeck(deck);
shuffleDeck(deck);
reset(&deckStack);
for (i = 0; i < DECKSZ; i++) {
push(deck[i], &deckStack);
}
do {
reset(&handStack);
for (i = 0; i < HAND_SIZE; i++) {
push(pop(&deckStack), &handStack);
if (isEmpty(&deckStack)) {
reset(&handStack);
shuffleDeck(deck);
reset(&deckStack);
for (j = 0; j < DECKSZ; j++) {
push(deck[j], &deckStack);
}
}
hand[i] = handStack.s[i];
}
numHands += 1;
arrangeHand(hand);
flushCount += isFlush(hand);
straightCount += isStraight(hand);
xOfAKindCount += isXOfAKind(hand, 2, 0);
straightFlushCount += isStraightFlush(hand);
fullHouseCount += isFullHouse(hand);
isTwoPairCount += isTwoPair(hand);
printf("Flushes:%d Straights:%d SF's:%d Number of Hands:%d\r",
flushCount, straightCount, straightFlushCount, numHands);
} while (1);
printf("\n");
return EXIT_SUCCESS;
}
My issue is my variable declared inside my function, result, is never set to 1 to indicate whether or not the hand is a straight, which therefore means my straightCount variable always remains at a value of zero. I do not have access to a debugger and in my mind the code I have makes sense. I'm new to programming in C, so if anybody could help me point out what is wrong with my function, I'd appreciate it. Thanks!
int isStraight(card hand[]) {
int step = 0;
for(int i = 1;i < HAND_SIZE; i++)
if(hand[i].pip != hand[i-1].pip+1)
/* Substitute step with i!=1 if over-edge invalid */
if(step || hand->pip != 1 || hand[i].pip != hand[i-1].pip+13-HAND_SIZE)
return 0;
else
step = 1;
return 1;
}
Right, after reading the code again, there are not enogh cards...
for (i = 0; i < HAND_SIZE-1; ++i)
Then you care counting pairs, not just individual cards, so
If (count == HAND_SIZE-1)
for (i = 0; i < HAND_SIZE-1; i++) { means that you are testing HAND_SIZE-1 pairs (which is correct), with i from from 0 to HAND_SIZE-2, so count will never be HAND_SIZE.
You just need to change your test to if (count == HAND_SIZE-1)
Assuming that (a) pip values are 1=Ace, 2=Deuce, ... and (b) the hand is sorted before being passed to the function, and (c) hands are exactly five cards, here's a quick one:
int isStraight(card hand[]) {
int i;
// Handle Broadway special case
if (hand[0].pips == 13 && hand[1].pips == 12 && hand[2].pips == 11 &&
hand[3].pips == 10 && hand[4].pips == 1) return 1;
// This will handle the rest
for (i = 0; i < (HAND_SIZE-1); i += 1) {
if (hand[i].pips != hand[i+1].pips) return 0;
}
return 1;
}
Also, I wouldn't use a structure for cards. Using a single integer is much faster and more versatile. Check out http://etceterology.com/blog/2013/5/23/representing-playing-cards-in-software

Resources