What exactly qualifies as a declaration of an identifier? - c

I am trying to construct some code such that it takes a user's input, runs one loop, takes the end value of that loop, and then runs that value through a second loop (I am also adding to a counter each time a loop runs and printfing it at the end), this was my attempt at coding this:
{
float input = get_float("%s", "Input: ");
float w = input * 100;
{
int c = 0;
for (int q = w; q > 24; q = q - 25)
{
c++;
}
for (int d = q; d > 9; d = d - 10)
{
c++;
}
printf("%i", c);
}
}
The error I receive is error: use of undeclared identifier 'q'. I thought that, since it was used earlier in the code, it wouldn't be a problem to identify it later on, though obviously that's not true. Any advice on either now to properly declare 'q' would be appreciated- or perhaps my entire approach is simply misguided?

The q declared in the loop is only available in the loop. You should declare it before the loop to make it available after the loop.
{
float input = get_float("%s", "Input: ");
float w = input * 100;
{
int c = 0;
int q; // declare q before the loop
for (q = w; q > 24; q = q - 25) // no declaration of q here
{
c++;
}
for (int d = q; d > 9; d = d - 10)
{
c++;
}
printf("%i", c);
}
}

When you declare q in the first loop it exists only inside this one loop as a local variable
Declaring the variable outside the for scope will leave it accessible on the second loop
{
float input = get_float("%s", "Input: ");
float w = input * 100;
{
int c = 0;
int q;
for (q = w; q > 24; q = q - 25)
{
c++;
}
for (int d = q; d > 9; d = d - 10)
{
c++;
}
printf("%i", c);
}
}```

for (int q = w; q > 24; q = q - 25) <- q is ok in this block
for (int d = q; d > 9; d = d - 10) <- q doesn't exist within this block
Add int q; below int c = 0; and modify for (int q = w; q > 24; q = q - 25) to for (q = w; q > 24; q = q - 25)

Related

C program chasing and I can't find the mistake

I just started learning programing and I'm having issues with my C code. The idea is to create a squared array sized [m][m] and fill the lateral and one diagonal spaces with 'n' (the user input determine the value of 'm' and 'n'), and then fill the rest of the spaces with numbers following a pattern. But every time it starts to fill the spaces it just crashes without pointing any warning or error.
Here is the code:
#include<stdlib.h>
#include<stdio.h>
int M[100][100] = {}, l, c;
int ImpMat(int m)
{
int l, c;
for(l = 0; l < m; l++)
{
printf("\n");
for(c = 0; c < m; c++)
printf("%i ", M[l][c]);
}
}
int Matriz(int m, int n)
{
int l, c;
for(l = 0; l < m; l++)
{
for(c = 0; c < m; c++)
{
if(c == 0 || c == m - 1 || c + l == m - 1)
M[l][c] = n;
else
M[l][c] = 0;
}
}
}
int NumMatI(int m)
{
int l, c, p, q;
for(l = 2; l < m; l++)
for(c = m -2; c >= 1; c++)
{
p = l - 1;
q = c + 1;
if(l + c > m - 1)
M[l][c] = M[p][c] + M[p][q];
}
}
int main()
{
int m, n;
printf("Type the value of 'm': ");
scanf("%i", &m);
printf("Type the value of 'n': ");
scanf("%i", &n);
Matriz(m, n);
NumMatI(m);
ImpMat(m);
return 0;
}
The function 'ImpMat' just prints the array, the 'Matriz' creates the array (the size is limited to 100) and 'NumMatI' is where it tries to fill the array.
I already realised the function 'NumMatI' is the one crashing the program, but can't find what is causing it.
I'm using Dev-C++.
In for(c = m -2; m >= 1; c++), the comparison should involve c somehow.

I assigned a long variable but the error message claims it´s an int

#include <stdio.h>
#include <cs50.h>
int main(void)
{
long card;
do
{
card = get_long("Type crdit card number\n");
}
while (card < 0);
long c = card;
int i = 1;
for (long o = 10; c >= 10;o *= 10, i++)
{
c = c / 10;
}
for (int h = 0, o = 10; h < i; h++, o *= 10)
{
c = card;
c = c % o;
printf("%ld\n", c);
printf("%ld\n", o);
}
}
I'm working on an assignment that requires that I work with credit cards numbers, so I've been using long variables, such as the 'o' on line 14, but I keep getting "format specifies type 'long' but the argument has type 'int'" as an error message when I try to print it, and I have no clue as to why. I'm quite new to programming so this might be just a beginner's mistake, so any help is deeply appreciated.
In the loop
for (int h = 0, o = 10; h < i; h++, o *= 10)
{
c = card;
c = c % o;
printf("%ld\n", c);
printf("%ld\n", o);
}
o is declared as int. You should also declare it as long.
for (long h = 0, o = 10; h < i; h++, o *= 10) /* use long instead of int */
{
c = card;
c = c % o;
printf("%ld\n", c);
printf("%ld\n", o);
}

Searching for a substring in 2d array in C

This is something for searching a substring In a 2d array
int left_to_rigth(char matrix[ROW][COLUNM], char str1[])
{
int i = 0, j, counting = 0, wordcnt;
int length = computeLength(str1); //returns legth of string
int index = -1;
for (i = 0; i < ROW; i++)
{
for (j = 0; j < COLUNM; j += 1)
{
if (matrix[i][j] == str1[0])
{
for (wordcnt = 0; wordcnt < length; wordcnt++)
{
if (matrix[i][j + wordcnt] == str1[wordcnt])
{
counting++;
}
}
if (counting == length)
{
index = (i *12) + j;
}
}
}
}
return index;
}
The output:
Enter the string to be searched in the puzzle:
SHOUT
position in the puzzle: 12
PUZZLE(MATRIX)
X T Z M Q Y K C E C F H -->0 1 2 3 4 5 6 7 8 9 10 11
*S H O U T* E X O E A P I -->12 13 14 ------------23
X G T L Q B E L T N F K
A I R I D Z A L L I O D
M E I E T Y S E H R T I
A W B R N E T C W O H X
N O U I R U Z T S C C T
U D T P E C J I E H R U
A L E M C S Y O N I U R
L V *K E R E M* N I P H E
E A N B U R E J O N C Y
A W I I I J N J R U Y F
D W T N T H E N P J Y T
E Q L Z D I L E M M A B
R C I T E N G A M T P C
So the function returns the starting point of SHOUT which is 12 but when I try to search for the word KEREM it should give me 110 but instead it return -1 which says that the word doesnt exist.
It seems like the code only searches for the first 3 lines every input I enter after that returns -1. Could you please help I am a beginner
This is just the first part I need to make it so that it searches in every direction I can either write 4 seperate functions and call them if they dont return -1 but I need to get this working first
Okay, I've done a few speedups and simplifications.
No need for a separate counting [for left-to-right and right-to-left, at least] as you can use wordidx
Also, once you find a match on the inner loop, there is no need to continue with it. And, you can stop the outer loop early
It's faster to calculate the length of str1 outside of the call and pass length as an argument. Also, strlen should work just fine.
On left-to-right, there is no need for j to go all the way to COLUMN - 1 as the last N slots can not match if there isn't enough room on the matrix line to fulfill the remaining string length.
Also, it's undefined behavior because you'll spill over into the next row. This would be harmless [but wrong result] except for the last row, where you'll go beyond the end of the entire matrix.
So, I added a jmax value of COLUMN - length
The right-to-left is slightly trickier. The jmax trick is critical.
So, here are the two functions [they compile cleanly, but I've not tested them]:
#include <string.h>
#define ROW 10
#define COLUMN 10
int
left_to_right(char matrix[ROW][COLUMN], const char *str1, int length)
{
char *matcur;
int i;
int j;
int wordidx;
int jmax = COLUMN - length;
int index = -1;
jmax += 1;
for (i = 0; i < ROW; ++i) {
for (j = 0; j < jmax; ++j, ++matcur) {
matcur = &matrix[i][0];
if (matcur[0] != str1[0])
continue;
for (wordidx = 1; wordidx < length; ++wordidx) {
if (matcur[wordidx] != str1[wordidx])
break;
}
if (wordidx == length) {
index = (i * COLUMN) + j;
break;
}
}
if (index >= 0)
break;
}
return index;
}
int
right_to_left(char matrix[ROW][COLUMN], const char *str1, int length)
{
const char *matcur;
int i;
int j;
int wordidx;
int jmax = COLUMN - length;
int index = -1;
for (i = 0; i < ROW; ++i) {
matcur = &matrix[i][jmax];
for (j = jmax; j >= 0; --j, --matcur) {
if (matcur[0] != str1[0])
continue;
for (wordidx = 0; wordidx < length; ++wordidx) {
if (matcur[wordidx] != str1[wordidx])
break;
}
if (wordidx == length) {
index = (i * COLUMN) + j;
break;
}
}
if (index >= 0)
break;
}
return index;
}

Program in C , working with 3 digits but not working with 5 digits

145 = sum of 1! + 4! + 5!. I need to write a program in C, that finds the 5 digit numbers that have this property.
I have written the code successfully for the 3 digits. I used the same code for 5 digits, but it cant find any number.
I would like to help me with my solution, in order for me to see where am I wrong.
#include <stdio.h>
int factorial(int n);
main() {
int pin[5];
int q = 1;
int w = 0;
int e = 0;
int r = 0;
int t = 0;
int result = 0;
int sum = 0;
for (q = 1; q <= 9; q++) {
for (w = 0; w <= 9; w++) {
for (e = 0; e <= 9; e++) {
for (r = 0; r <= 9; r++) {
for (t = 0; t <= 9; t++) {
pin[0] = q;
pin[1] = w;
pin[2] = e;
pin[3] = r;
pin[4] = t;
int factq = factorial(q);
int factw = factorial(w);
int facte = factorial(e);
int factr = factorial(r);
int factt = factorial(t);
sum = factq + factw + facte + factr + factt;
result = 10000 * q + 1000 * w + 100 * e + 10 * r + t * 1;
if (sum == result)
printf("ok");
}
}
}
}
}
}
int factorial(int n) {
int y;
if (n == 1) {
y = 1;
} else if (n == 0)
y = 0;
else {
y = n * factorial(n - 1);
return y;
}
}
Your factorial function doesn't return a value in all cases:
int factorial (int n) {
int y;
if (n==1) {
y = 1;
}
else
if (n==0)
y = 0;
else {
y = n * factorial(n-1);
return y;
}
}
It only returns a value when it makes a recursive call. The base cases don't return anything. Failing to return a value from a function and then attempting to use that value invokes undefined behavior.
Move the return statement to the bottom of the function so it gets called in all cases. Also the value of 0! is 1, not 0.
int factorial (int n) {
int y;
if (n<=1)
y = 1;
else
y = n * factorial(n-1);
return y;
}
Also, when you find the target value you probably want to print it:
printf("ok: %d\n", result);
dbush's answer is accurate in pointing out why your code didn't work. This is an alternative solution to reduce the amount of calculation done by your program by not re-calculating the factorial of each numeral every step of the way. The way your program currently works, it winds up being around 500,000 calls to the factorial function from your nested loop, and then in turn recursively calls the function on average 4ish times for each call from the nested loop, so that's around 2 million calls to factorial. The more digits you tack on, the faster that number grows and more expensive it gets. To avoid all these recalculations, you can create a Look-up table that stores the factorial of the numerals [0-9] and just looks them up as needed.
You can calculate these values ahead of time and initialize your LUT with these values, but if hypothetically you wanted them to be calculated by the program because this is a programming assignment where you can't cut out such a step, it is still pretty trivial to populate the LUT.
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <inttypes.h>
void populate_lut(uint32_t *lut);
int main(void) {
// lut is an array holding the factorials of numerals 0-9
uint32_t lut[10];
populate_lut(lut);
for (uint8_t q = 1; q <= 9; q++) {
for (uint8_t w = 0; w <= 9; w++) {
for (uint8_t e = 0; e <= 9; e++) {
for (uint8_t r = 0; r <= 9; r++) {
for (uint8_t t = 0; t <= 9; t++) {
// now instead of calculating these factorials, just look them up in the look-up table
uint32_t sum = lut[q] + lut[w] + lut[e] + lut[r] + lut[t];
uint32_t result = 10000 * q + 1000 * w + 100 * e + 10 * r + t * 1;
if (sum == result) {
printf("Solution: %" PRIu32 "\n", result);
}
}
}
}
}
}
}
// populate your lookup table with the factorials of digits 0-9
void populate_lut(uint32_t *lut) {
lut[0] = 1;
lut[1] = 1;
for(uint8_t i = 2; i < 10; ++i) {
lut[i] = lut[i-1] * i;
}
}

why is this code giving this output - "HCF is: 1" whenever a%b != 0?

This program is made to find the HCF of two integers a and b by the formula/algorithm - 'a = bq +r' where a and b are two numbers, q being the quotient and r is the remainder.
here is the code.
#include <stdio.h>
int main() {
int a, b;
printf("enter both numbers a>b to find HCF\n");
scanf("%d %d",&a, &b);
int q, r, hcf;
if(a%b == 0) {
r = 0;
hcf = r;
} else {
q = a/b;
r = a%b;
}
int i;
for(i = r; i = 0;) {
a = b;
b = i;
hcf = b;
q = a/b;
i = a%b;
}
printf("HCF is: %d", hcf);
return 0;
}
The for loop is not correct. You need to use == instead of =. The = operator is for assignment, == is for comparison. Also, you want the loop to stop when i == 0 so the condition should be i != 0. The following loop works for me:
for(i = r; i != 0; ) {
a = b;
b = i;
hcf = b;
i = a%b;
}

Resources