For input of n = 10, i am getting a weird output :
pid = 31456
Sum of Odd series : 25
pid = 31456
Sum of Even series : 30
pid = 31456
Code
#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
pid_t child_pid;
int i, j, k, n;
int sum;
//printf("Enter the last number of series : ");
scanf("%d", &n);
printf("pid = %d\n", getpid());
for(i = 0; i < 2; i++)
{
child_pid = fork();
if (child_pid < 0)
{
printf("Failed to create child process . . .");
return 1;
}
else if (child_pid == 0)
{
if (i == 0) //find the sum of odd series
{
sum = 0;
for(j = 1; j <= n; j += 2)
sum += j;
printf("Sum of Odd series : %d\n", sum);
exit(0);
}
else if (i == 1) //find the sum of even series
{
sum = 0;
for(j = 2; j <= n; j += 2)
sum += j;
printf("Sum of Even series : %d\n", sum);
exit(0);
}
}
else
{
wait(&child_pid);
}
}
return 0;
}
Ideone link : ideone.com/TyIkJa
You will have to change your code as below.
if (childs[i] == 0)
{
if (i == 0) //find the sum of odd series
{
for(j = 1; j <= n; j += 2)
sum += j;
printf("Sum of odd series : %d\n", sum);
exit(0);
}
else if (i == 1) //find the sum of even series
{
for(k = 2; k <= n; k += 2)
sum += k;
printf("Sum of even series : %d\n", sum);
exit(0);
}
else
{
wait(&childs[i]);
}
The reason is both children and parent have their own copies of sum. So when you are ending the parent still has sum=0 ,but these values are updated for "sum" of child1 and "sum" of child2.
When you fork a process, then parent and child are initially
more or less exact copies, including the values of variables,
except for the return code of fork().
But the key word there is copies.
Those two processes are now independent and variables,
"global" or not, *are not connecte*d in any way.
Related
This loop checks the previous element in an array. The question is how can it be avoided to check the arr[0][0] with its previous element which causes undefined behavior?
Here is the code so far but it has this issue with the the first element being checked with its previous element.
int main()
{
int arr[2][4];
int k, n;
for (k = 0; k < 2; k++) {
for (n = 0; n < 4; n++) {
do {
printf("Provide a number");
scanf("%d", &arr[k][n]);
printf("This is %d in the position[%d][%d]\n", arr[k][n], k, n);
if (n==0) break;
printf("The arr[k][n] is %d and the arr[k][n-1] is %d and n-1 means %d\n", arr[k][n], arr[k][n - 1], n - 1);
} while (arr[k][n] <= arr[k][n - 1]); //Here is the issue
}
}
for (k = 0; k < 2; k++) {
for (n = 0; n < 4; n++) {
printf("%d\n", arr[k][n]);
}
}
}
The issue:
Adding the if (n==0) break; causes the program to allow adding smaller numbers than the ones inserted so far. While not including this line causes undefined behavior. How can this be fixed?
This is how it works now, which is not correct:
2 3 4 5
2 4 5 6
The printf statements are only for the purpose of viewing what is going on.
You only check with previous column. That is not related to your break but due to broken logic.
You could do it like this:
int main()
{
int arr[2][4];
int k, n;
int last_number, new_number;
for (k = 0; k < 2; k++) {
for (n = 0; n < 4; n++) {
do {
printf("Provide a number");
scanf("%d", &new_number);
printf("This is %d in the position[%d][%d]\n", new_number, k, n);
if (n==0 && k == 0)
break; // Don't check for increasing values.
} while (new_number < last_number);
arr[k][n] = new_number;
last_number = new_number;
}
}
for (k = 0; k < 2; k++) {
for (n = 0; n < 4; n++) {
printf("%d\n", arr[k][n]);
}
}
}
Change
while (arr[k][n] <= arr[k][n - 1]);
to
while (n > 0 && arr[k][n] <= arr[k][n - 1]);
This works because && short circuits the test when n == 0 and does not do the second test.
You will also need to fix the print statement.
I was wondering, how can I add up the divisors displayed once I run my code?
#include <stdio.h>
#include <stdlib.h>
int main()
{
int n, i;
scanf("%d", &n);
for(i = 1; i < n; i++)
{
if(n % i == 0)
{
printf("%d\n", i);
}
}
return 0;
}
If I were to enter, say, 25, it would print out 1, 5. I was wondering how to add up the two numbers 1 and 5?
Could it be as simple as this? You will want to use a simple increment operator (+=), to increment the variable sum.
int main(void)
{
int n, i, sum = 0;
if( scanf("%d", &n)!= 1){
fprintf(stderr,"Error in input\n");
exit(EXIT_FAILURE);
}
for(i = 1; i < n; i++)
{
if(n % i == 0)
{
printf("%d\n", i);
sum += i;
}
}
printf("Sum of divisors: %d\n", sum);
return 0;
}
How to add up divisors of an integer n?
Iterating n times as with for(i = 1; i < n; i++) can take a long time when n is some high value, especially if code used 64-bit integers. Instead only iterate sqrt(n) times - much faster
int factor_count(int number) {
if (number <= 1) {
return TBD_Code(number); // OP needs to define functionality for these cases.
}
int sum = 1;
int quotient;
int divisor = 1;
do {
divisor++;
quotient = number/divisor;
int remainder = number%divisor;
if (remainder == 0) {
sum += divisor;
if (quotient > divisor) sum += quotient;
}
} while (divisor < quotient);
return sum;
}
Additional improvements noted here.
I made in C a program in Linux of multiplication of matrices of order 1000 A and B. And now I have to add processes!
And now I have to add 4 processes in the multiplication that will result in array C.
1 process for calculating from 0 to 249;
2 process for calculating from 250 to 499;
3 process for calculating from 500 to 749;
4 process for calculating from 750 to 999;
Multiplication is working correctly;
I do not understand much of processes, and the problem lies in the parts of the processes, I can not do what I need;
Follow the code below:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/shm.h>
int id;
int main(){
int i;
int j;
int row;
int col;
int order;
long T1;
long T2;
float delta;
int process_1;
int process_2;
int process_3;
int process_4;
printf("Enter the order of the square matrices A and B: ");
scanf("%d", &order);
T1 = clock();
printf("\nThe square matrices A and B, are order matrices %d",order);
order = order - 1;
row = order;
col = order;
float A[row+1][col+1];
float B[row+1][col+1];
for(i = 0; i <= row; i++){
for(j = 0; j <= col; j++){
printf("\n\nEnter the value of the array A[%d][%d]: ",i+1,j+1);
scanf("%f", &A[i][j]);
printf("\nEnter the value of the array B[%d][%d]: ",i+1,j+1);
scanf("%f", &B[i][j]);
}
}
printf("\nThe multiplication of matrices A and B:\n\n");
id = shmget(IPC_PRIVATE, 100, 0600);
process_1 = fork();
process_2 = fork();
process_3 = fork();
process_4 = fork();
int *a;
a = shmat(id,0,0);
printf("\n\nprocess 1:\n\n");
if(process_1 == 0){
int P1 = 0;
if(P1 <= 249){
for(i = 0; i <= row; i++) {
for(j = 0; j <= col; j++) {
float C[row+1][col+1];
for(int AUX = 0; AUX <= order; AUX++) {
C[i][j] += A[i][AUX] * B[AUX][j];
}
printf("%.2f ",C[i][j]);
}
printf("\n");
}
}
exit(0);
}
printf("\n\nprocess 2:\n\n");
if(process_2 == 0){
int P2 = 250;
if(P2 >=250 && P2 <= 499){
for(i = 0; i <= row; i++) {
for(j = 0; j <= col; j++) {
float C[row+1][col+1];
for(int AUX = 0; AUX <= order; AUX++) {
C[i][j] += A[i][AUX] * B[AUX][j];
}
printf("%.2f ",C[i][j]);
}
printf("\n");
}
}
exit(0);
}
printf("\n\nprocess 3:\n\n");
if(process_3 == 0){
int P3 = 0;
if(P3 >=500 && P3 <= 749){
for(i = 0; i <= row; i++) {
for(j = 0; j <= col; j++) {
float C[row+1][col+1];
for(int AUX = 0; AUX <= order; AUX++) {
C[i][j] += A[i][AUX] * B[AUX][j];
}
printf("%.2f ",C[i][j]);
}
printf("\n");
}
}
exit(0);
}
printf("\n\nprocess 4:\n\n");
if(process_4 == 0){
int P4 = 0;
if(P4 >=750 && P4 <= 999){
for(i = 0; i <= row; i++) {
for(j = 0; j <= col; j++) {
float C[row+1][col+1];
for(int AUX = 0; AUX <= order; AUX++) {
C[i][j] += A[i][AUX] * B[AUX][j];
}
printf("%.2f ",C[i][j]);
}
printf("\n");
}
}
exit(0);
}
waitpid(process_1, NULL, 0);
waitpid(process_2, NULL, 0);
waitpid(process_3, NULL, 0);
waitpid(process_4, NULL, 0);
T2 = clock();
delta = (float)(T2-T1)/CLOCKS_PER_SEC;
printf("\n\Time %.5f seconds\n\n",delta);
return 0;
}
How can I fix this?
I would start from changing type int to pid_t for process identifiers, e.g.:
pid_t process_1;
and then would change:
process_1 = fork();
process_2 = fork();
process_3 = fork();
process_4 = fork();
to
pid_t pid = fork();
if (pid) {
process_1 = pid;
pid = fork();
}
if (pid) {
process_2 = pid;
pid = fork();
}
if (pid) {
process_3 = pid;
pid = fork();
}
if (pid)
process_4 = pid;
the idea is that we do fork() only in the parent process and skip forking in a child process. Otherwise your code forks processes as a tree, each child and parent processes call the next fork() after the previous, then their children do the same and so on four times.
The code above does not check if fork() returns the error code (-1). In the ideal world it is strongly recommended.
From the fork(2) man page:
Return Value
On success, the PID of the child process is returned in the parent,
and 0 is returned in the child. On failure, -1 is returned in the
parent, no child process is created, and errno is set appropriately.
So I created a program that generates a random 4x4 matrix, with values ranging from 0 to 17. Afterwards, it would calculate and print the sum of each rows and columns. The problems are, (1) values of row sums are incorrect, (2) the last element, which is the m[4][4], seems to double in value, giving an incorrect value for the sum of Column 4 as well. Here is the code:
srand(time(NULL));
printf("Generating matrix... ");
getch();
printf("\n\n");
for (i = 1; i <= 4; i++) {
for (j = 1; j <= 4; j++) {
m[i][j] = rand() % 17;
printf("%d\t", m[i][j]);
if (i == 1) { // Calculation of Row Sums
rSum[1] += m[i][j];
} else if (i == 2) {
rSum[2] += m[i][j];
} else if (i == 3) {
rSum[3] += m[i][j];
} else if (i == 4) {
rSum[4] += m[i][j];
}
if (j == 1) { // Calculation of Column Sums
cSum[1] += m[i][j];
} else if (j == 2) {
cSum[2] += m[i][j];
} else if (j == 3) {
cSum[3] += m[i][j];
} else if (j == 4) {
printf("\n");
cSum[4] += m[i][j];
}
}
}
getch();
printf("\n\n");
for (i = 1; i <= 4; i++) { // Printing of Values
printf("Sum of Row %d: %d\n", i, rSum[i]);
printf("Sum of Column %d: %d\n", i, cSum[i]);
printf("-----------------------------------------------\n");
}
return 0;
Arrays are 0 based in C. You should change all your loops to iterate this way:
for (i = 0; i < 4; i++) {
And also change other parts of your code where you use explicit index values. This part can be simplified drastically.
The arrays rSum and cSum must be initialized to 0. Failure to do it might explain the incorrect values computed by your program.
Here is an improved version:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int m[4][4];
int rSum[4] = { 0 };
int cSum[4] = { 0 };
int i, j;
srand(time(NULL));
printf("Generating matrix... ");
getch();
printf("\n\n");
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
m[i][j] = rand() % 17;
printf("%d\t", m[i][j]);
rSum[i] += m[i][j]; // Calculation of Row Sums
cSum[j] += m[i][j]; // Calculation of Column Sums
}
printf("\n");
}
getch();
printf("\n\n");
for (i = 0; i < 4; i++) { // Printing of Values
printf("Sum of Row %d: %d\n", i, rSum[i]);
printf("Sum of Column %d: %d\n", i, cSum[i]);
printf("-----------------------------------------------\n");
}
return 0;
}
I want to calculate the average of the prime numbers between 1 to 10 and I have written a program which is as follows:
#include <stdio.h>
int main()
{
int i, j, sum = 0, count = 0;
loop1:
for(i = 2; i <= 10; i++)
{
for(j = i - 1; j > 1; j--)
{
if(i % j == 0)
{
goto loop1;
}
}
sum = sum + i;
count++;
}
printf("The avg:%d", (sum / count));
return 0;
}
Please help me whether the program is correct.
Simple answer for you:
#include <stdio.h>
int main() {
float sum = 0, count = 0, average;
for(int i=2; i<11; i++){
for(int j=2; j<=i; j++){
if(j==i){
sum+=i;
count++;
}else if(i%j==0){
break;
}
}
}
average=sum/count;
printf("Average = %.2f", average);
return 0;
}
Please ensure you do not make a habit of usinggoto: statements. Your program is incorrect. Here, when the statement
if(i % j == 0)
returns true, thegoto: statement takes control to the beginning of the parent for loop and the loop will run from start again. This way, you will never get your desired output. As per your question, your solution is wrong. A modified approach is
#include <stdio.h>
int main()
{
int i, j, sum = 0, count = 0,flag;
for(i = 2; i <= 10; i++)
{
flag=0;
for(j = i - 1; j > 1; j--)
{
if(i % j == 0)
{
flag=1;
break;
}
}
if(flag==0)
{
sum = sum + i;
count++;
}
}
printf("The avg:%d", (sum / count));
return 0;
}
What do you mean by "Correct" ?
If correct to you means that it works: well that's easy to verify for yourself.
If correct means that you are hitting the best practices, well then, nope, you missed them I'm afraid.
goto: about the most easy of all "do not use that" signs.
A "better" approach would be to write a function that tests if a number is a prime or not.