Some more explanation about an array example I found online - c

I'm just starting out to learn program in C and am trying to get my head around arrays. I found this example online but don't understand how it works. Here is the code:
#include <stdio.h>
int main () {
int n[ 10 ]; /* n is an array of 10 integers */
int i,j;
/* initialize elements of array n to 0 */
for ( i = 0; i < 10; i++ ) {
n[ i ] = i + 100; /* set element at location i to i + 100 */
}
/* output each array element's value */
for (j = 0; j < 10; j++ ) {
printf("Element[%d] = %d\n", j, n[j] );
}
return 0;
}
What I don't understand here is how int j links to int i. In the output, at the printf line, I don't understand why it is not:
printf("Element[%d] = %d\n", i, n[i]);
Why do we need another int j?
And another thing I don't understand is the %d's in that line. Why %d and not %i? d hasn't been declared anywhere right?
Any deeper explanation than on the website where I found this example would be appreciated. Thank you.

Why do we need another int j?
You don't. I'm assuming the author was just demonstrating that you can use any variable to index into an array, as long as the variable has the right type (pretty much any integral type) and holds a value in the correct range.
Array indices can be any integral expression, whether it's an integral constant (a[5]), a variable (a[i], a[j]), or a more complex expression (a[i+j], a[foo(i)], a[1+j*k/2], etc.). All that matters is that the expression has an integral type, and that its result is in the correct range (0 to N-1, where N is total number of elements in the array).
And another thing I don't understand is the %d's in that line. Why %d and not %i? d hasn't been declared anywhere right?
%d is a conversion specifier - it has nothing to do with any variable, and does not need to be declared separately. Conversion specifiers in the format string tell printf the number and types of additional arguments, and how to format those values for display.
In the line
printf("Element[%d] = %d\n", i, n[i]);
the %d specifiers in the format string tell printf that i and n[i] both have type int, and that they are to be formatted as decimal integers (as opposed to hex or octal, for example).
Here's an incomplete list of conversion specifiers:
Specifier Argument Type Output format
--------- ------------- -------------
%d,%i int decimal integer
%u unsigned int decimal integer (non-negative)
%f double decimal floating point
%x,%X unsigned int hexadecimal integer (non-negative)
%o unsigned int octal (non-negative)
%c char single character
%s char * text
Check your handy C reference manual for a complete list. If you don't have a handy C reference manual, I recommend Harbison & Steele's C: A Reference Manual.

Agreeing with # Eugene Sh, that in this case, j is indeed an extra variable.
The coding would be as shown below, and would return the same output.
for (i = 0; i < 10; i++) {
printf("Element[%d] = %d\n", i, n[i]);
}
And another thing I don't understand is the %d's in that line.
The printf() family of functions uses % character as a placeholder. This is a format specifier and does not require initialization. When a % is encountered, printf reads the characters following the % to determine what to do:
%s - Take the next argument and print it as a string
%d - Take the next argument and print it as an int
Sooner or later you might also encounter %s, which indicates that you're expecting a String to be your first print parameter.
Hope this helps.

What I don't understand here is how int j links to int i
They don't "link" and there is actually no connection between the two. The author simply used another integer (j) to avoid confusion.
As for your suggestion:
In the output, at the printf line, I don't understand why it is not:
printf("Element[%d] = %d\n", i, n[i]);
It is perfectly fine to do so if you make sure to use i as the loop variable for the second loop as well like so:
for (i = 0; i < 10; i++ ) {
printf("Element[%d] = %d\n", i, n[i] );
}
And another thing I don't understand is the %d's in that line. Why %d and not %i? d hasn't been declared anywhere right?
%d is a type modifier that tells the printf function to replace it with a decimal number when printing. It has nothing to do with some sort of variable named d. Your confusion might originated from the fact that there is also a %i modifier for printf but it is less commonly used. Refer to this wiki for more details.

Related

C for loop goes on forever and I think I wrote the program wrong

This is my homework assignment:
And this is my code:
#include <stdio.h>
int main() {
char v[2] = {'A', 'I'};
char c[3] = {'n', 's', 't'};
int i;
for (i = 0; i < c[i]; i++) {
printf("%d %d %d %d %d %d", c[6]);
for (i = 0; i < v[i]; i++) {
printf("%d %d", v[2]);
}
}
return 0;
}
It seems to go on forever and I don't know what to do. Keep in mind that I am new to C, so I tried my best.
it seems you want to write the first letter of v[] combined with each letter of c[]
Then write the second letter of v[] combined with each letter of c[]
This hints the first/outer loop would be stepping through the array v[]
This hints the second/inner loop would be stepping through the array c[]
This hints within the inner loop would be outputting the current letter from v[] followed by the current letter from c[] followed by a space.
remembering that / (divide) has a higher precedence than < see C precedence table:
(remembering that sizeof() returns the number of characters in an object so obtaining the number of entries in an array is the total size of the array, in characters, divided by the number of characters in the first element of the array)
how to step through array v[]:
for( int i=0; i < sizeof(v) / sizeof(v[0]); i++ )
how to step though array c[]:
for( int j=0; j < sizeof(c) / sizeof(c[0]); j++ )
within the inner loop to print the current entry in v[] followed by the current entry in c[] followed by a space:
printf( "%c%c ", v[i], c[j] )
of course the above call to printf() places everything into the stdout I/O stream buffer and you actually want to display the output on the terminal, so after the nested loops exit, suggest:
printf( "\n" );
which is one way to flush the stdout buffer to the terminal.
Of course, all the above needs to be in a main() function
Of course, to use printf() need to include the header file: stdio.h
If you need clarification on any of the details, post a comment to this answer.
regarding:
printf("%d %d %d %d %d %d", c[6]);
the number of `output format conversion specifiers must match the number of values to be output. In the current statement, 6 output specifiers does not match one value to be output.
Also, the c[] array only has 3 elements and C is zero based, so the only valid indexes are 0..2, not 6. Accessing index 6 results in accessing beyond the end of the array, which results in undefined behavior.

How does this function print the correct HEX of the given argument

During my time reading CS:APP 3rd Edition, i stumbled up on this piece of code, who knows whilst reading into the book more i might get a proper explanation but until now i do not quite understand how this retrieves the correct Hexadecimal number.
I hope someone here would be able to give me a thorough explanation.
What does casting a pointer to the adress of a piece of memory do?
typedef unsigned char *byte_pointer;
void show_bytes(byte_pointer start, size_t len)
{
int i;
for (i = 0; i < len; i++)
printf(" %.2x", start[i]);
printf("\n");
}
void show_int(int x)
{
show_bytes((byte_pointer) &x, sizeof(int));
}
And by how, do i mean how is the integer stored into the memory, because when i print it as a %d with as example 100 as the given int. it will print:
100 0 0 0
however when i use 1000, it will print:
232 3 0 0
&x gives the pointer where x is memorized, since x is an int, it gives a pointer to an int (4 bytes).
(byte_pointer) &x gives instead the pointer to a char (a single byte) so that the for loop can go through every single byte of the int (start[i] points to the i-th byte and not to the i-th int).
That prints each array element as a two digit hex number as the format %.2x shows. You can see it also written as %02x or %02X (using uppercase letters) and preceded by a space. You can see it printed also as:
while (len--) printf(" %02x", start++);
in a way more compact (and difficult to understand to newcomers)

Is it possible to make some loop which scans always one number and one string more than once? (Part of my homework)

so in my CS course we have to make a calculator which reads input and then calculates the result after the = sign has been read.
Input always consists of one number followed by operator.
I'm now struggling with the way of scanning the input. I want to use some loop which would always store it like:
scanf("%lf %s ", &in, c);
Note: the calculator goes one operation after other. Thus in example below the plus sign works only for 20 and 4, and only then the result takes the division sign and gets divided by 8. Then the new result gets negated by 'neg' string.
E.g.: Input: 20 + 4 / 8 neg =
Output: Result: -3
This is how I tried to solve it. My intention was to make the loop store each number into a new "box" of array, and then to store each string into the new "line" of char array. The 4 in op array is meant to set the max length of the string, because i know that the longest string that can occur is "sqrt".
I see that the '\n' in the condition of for is probably useless but can't figure out how to do it...
I'm thinking about using either for, or a while loop.
int main(){
double in[10];
char op[5][4];
for(int i=0; i<5;i++){
scanf("%lf %s ", &in[i], op[i][4]);
}
printf("%.3f %s", in[0], op[0][0]);
return 0;
}
//just a "skeleton" of the code. There's more to it, but here I submitted just the part that I'm struggling with.
For example if I run this code, I want to write a few numbers followed by operator into the input.
I expect it to print the first number and string (just to check whether the loop works).
But actually it does absolutely nothing and just gives me some large negative number as a return.
From the man page of scanf
int scanf(const char *format, ...);
as you can see first argument is of const char * type i.e you need to provide valid address.
With this
char op[5][4]; /* 5 char array, in each char array you can have 4 char's
* i.e op[row][0] to op[row][3]. There is no op[i][4]
*/
you can have
for(int i=0; i<5;i++){
scanf("%s",op[i]); /* op[i] itself address, so don't need & */
}
or
for(int i=0; i<5;i++){
for(int j=0; j<4; j++) {
scanf(" %c", &op[i][j]); /* storing char by char */
}
}
Also while printing here use %c as op[0][0] is of char type.
printf("%.3f %c", in[0], op[0][0]);
In a scanf format string, %s indicates you want to read a string, meaning it needs the address of where to put that string. You are passing op[i][4] for it, which is a char.

How to print a number if it is non-zero and blank otherwise using printf?

I have the following function and it is giving some weird output if i value is 0
Could someone explain me why this is behaving weird ? My intention is to print the value only if it non-zero and otherwise it should be blank
# include<stdio.h>
int main(int argc, char *argv[]) {
int i=0;
printf("Number is %d\n", i ? i : "");
return 0;
}
-> gcc print.c
print.c: In function 'main':
print.c:5: warning: pointer/integer type mismatch in conditional expression
-> ./a.out
Number is 4195848
I know I can do it like below, but I would like to do the same with above logic
if(i != 0) {
printf("%d", i);
} else {
printf("%s", "");
}
Specify a precision of 0:
printf("Number is %.0d\n", i);
From the C standard's description of the d format code, emphasis added (ยง7.21.6.3):
The int argument shall be converted to a signed decimal in the style "[-]dddd". The precision specifies the minimum number of digits to appear; if the value being converted can be represented in fewer digits, it shall be expanded with leading zeros. The default precision is 1. The result of converting zero with an explicit precision of zero shall be no characters.
This feature of printf is occasionally useful, particularly when producing tabular output in which you want 0 entries to not be printed. A format code such as %8.0d will right-justify an integer value in an 8-character field, printing eight spaces if the value is 0. (The field width is applied to the converted value.)
If you have to use conditional statement, you can plan to control the whole printf(), based on the value of i, like
int i=0;
i? printf("Number is %d\n", i): (void)i;
return 0;
or, in case, you want the Number is to be printed always, use it like
int i=0;
i? printf("Number is %d\n", i): puts("Number is");
return 0;
An answer to this silly question (might as well throw my hat into the ring)
i && printf("Number is %d\n", i);
Gets rid of the ternary operator as well!
Maybe something like this:
int main(void)
{
int i = 30;
return (i != 0) ? printf("Number is: %d", i) : i;
}

About left padding in C programming?

I searched through the website already, but I can't seem to find the solution that pertains to my problem:
Example:
printf("%s I love puppies", name);
this is my prinf statement, but how do I left pad in which it will add additional spaces with each for loop?
Edit:
Hello //int i is 0
Hello //int i is 1
Hello //int i is 2
Hello //int i is 3
I wanted to do something like this:
(in for loop)
space += " " //where space is first initialized as ""
Is there a function that is similar to this (in java) in C programming?
Edit: The thing is I have this : printf("%s I love puppies", name);
I was thinking of using int space = i (according to the loop counter) and then do printf("%s", space, "%s I love puppies", name); in printf but it says I have too many arguments...
You can supply the %s format conversion with a length (just like any other format code). So %10s will print at least 10 characters.
By default, strings are padded on the left with spaces. (That's the same as other format codes, too.) You can't change the character that printf pads with, but you can get it to pad on the right by using a -: %-10s.
Length specifications can be replaced with a *, which will cause printf to use an int parameter prior to the parameter being converted, and use its value as the length. (You can do this with precision values as well.)
I imagine that what you are trying to do is a variable indent. Putting the above together, you can do it like this:
for (int indent = 0; indent < 20; ++indent) {
printf("%*s%s\n", indent, "", the_string);
}
Perhaps perform a printf(" "); in a loop that uses the existing loop count as a limiting factor something like:
for( i=0; i<namelimit; i++ )
{
for(j=0; j<i; j++ )
{
printf(" ");
}
printf("%s\n",name);
}

Resources