This question already has answers here:
No compiler error when fixed size char array is initialized without enough room for null terminator
(2 answers)
Closed 6 years ago.
If we declare an array of characters in C
Ex:
char label[] = "Hello";
We will have an array in memory which looks like this
--------------------------
| H | e | l | l | o | \0 |
--------------------------
where the extra null byte is added at the end of the array.
Scenario 1:
char label[10] = "Hello";
------------------------------------------
| H | e | l | l | o | \0 | | | | |
------------------------------------------
where it will have an extra 4 unused locations.
Scenario 2:
Here if we have exactly a string with 10 characters, will the \0 (null byte) still be added, which makes the char array to hold 11 characters?
char label[10] = "0123456789";
-----------------------------------------
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
-----------------------------------------
OR
----------------------------------------------
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | \0 |
----------------------------------------------
Your understanding is almost correct:
char label[10] = "Hello";
will initialize a 10 byte char array with | H | e | l | l | o |\0|\0|\0|\0|\0|.
Whereas for the last case:
char label[10] = "0123456789";
the array is also 10 char long, initialized with | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |. This array is therefore not null terminated and should not be used as a C string.
Related
#include <stdio.h>
#include<string.h>
void double_string(char ary[])
{
char *start = ary;
// dont exactly know what is happening here nothing is getting printed when consoled
char *end = ary + strlen(ary);
char *org = end;
while(start<org)
{
*end = *start;
start++;
end++;
}
*end = '\0';
}
int main(void) {
char word[255] = {"TACsasasa"};
double_string(word);
printf("%s",word);
return 0;
}
I am unable to understand what is getting stored in character array "*end", I tried printing it but I am not getting any output printed..
char *end = ary + strlen(ary);
This line of code is taking the starting address of the char array in memory, adding the number of bytes inside the array, returned by strlen(), and essentially moving the pointer to the end. The end of the array is the null terminator. Printing that will show nothing as it takes it as an empty string.
Adding an unsigned int (or even a signed int!) is known as pointer arithmetic. It's legal and quite common in C code. You do have to be very careful about going out of the bounds of your memory buffer, though, or you will experience undefined behavior. This is bad. Fortunately, this code appears to be quite well behaved as long as the original string is less than half the length of its memory buffer.
Allow me to try some ASCII art to see if I can make clear what's going on in the double_string function. It starts with this:
char *start = ary;
char *end = ary + strlen(ary);
char *org = end;
At this point, your pointers look like this:
start end
| |
| org
| |
v V
----------------------------------------------------------------------------------
ary | T | A | C | s | a | s | a | s | a |\0 | | | | | | | | | | | ...
----------------------------------------------------------------------------------
Then we have the loop.
while(start<org)
{
*end = *start;
start++;
end++;
}
After the first loop iteration, it looks like this:
start end
| |
| org |
| | |
v V V
----------------------------------------------------------------------------------
ary | T | A | C | s | a | s | a | s | a | T | | | | | | | | | | | ...
----------------------------------------------------------------------------------
Second iteration:
start end
| |
| org |
| | |
v V V
----------------------------------------------------------------------------------
ary | T | A | C | s | a | s | a | s | a | T | A | | | | | | | | | | ...
----------------------------------------------------------------------------------
And so on. The loop continues as long as start is less than (to the left of, in my illustration) org:
start end
| |
org |
| |
V V
----------------------------------------------------------------------------------
ary | T | A | C | s | a | s | a | s | a | T | A | C | s | a | s | a | s | a | | | ...
----------------------------------------------------------------------------------
Now start<org is no longer true, because they're equal. They point to the same location. The loop terminates. All that's left to do is terminate the string with *end = '\0';:
start end
| |
org |
| |
V V
----------------------------------------------------------------------------------
ary | T | A | C | s | a | s | a | s | a | T | A | C | s | a | s | a | s | a |\0 | | ...
----------------------------------------------------------------------------------
I came upon a program which outputs 5. I don't know how. Please explain.
int main(void) {
int t[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }, *p = t;
p += 2;
p += p[-1];
printf("\n%d",*p);
return 0;
}
I expect the output to be 4.
the pointer moves from t[0] to t[2] here(p+=2;). In the next statement p+= p[-1], I believe pointer moves to t[1] whose value is 2 first and so increased by 2. So I expected output to be 4.
but the actual output is 5. Anyone, please explain?
p = t; // p = &t[0]
p += 2; // p = &t[2]
p += p[-1]; // p += 2; // p = &t[4]
At first, the pointer p points to the beginning of the array t. So it should be something like
p--
|
v
------------------------------------------
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
------------------------------------------
Now by
p += 2
p is increment according to pointer arithmetic. So that p is now pointing to 3.
p----------
|
v
------------------------------------------
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
------------------------------------------
p[-1] is same as *(p-1). ie, the value at the address p-1. This value is 2.
------ p[-1] or *(p-1)
|
|
------|-----------------------------------
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
------------------------------------------
After adding 2 to the current value of p, p would now be pointing to 5.
p------------------
|
v
------------------------------------------
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
------------------------------------------
So, when you print the value of *p, 5 is output.
How to print numbers from 1 to 10 using a loop in Brainfuck? Is it even possible?
I am looking for a solution to this issue.
+++++++++++++++++++++++++++++++++++++++++++++++++ Cell 0 to '1'
>++++++++++ cell 1 to '\n'
>+++++++++ cell 2 to 9 as counter
[ Print numbers 1 to 9
<< Data pointer to cell 0
.+ Print and increment cell 0
>. Data pointer to cell 1 and print the newline
>- Data pointer to cell 2 and decrement counter
] Loop till counter is 0
+++++++++ Set cell 2 to 9
[ Set cell 0 to '1'
<<- Data pointer to cell 0 and decrement
>>- Data pointer to cell 2 and decrement counter
] Loop till counter is 0
<<. Data pointer to cell 0 and print '1'
-. Decrement cell 0 and print '0'
>. Data pointer to cell 1 and print newline
Readable version:
+++++++++++++++++++++++++++++++++++++++++++++++++>
++++++++++>
+++++++++[<<.+>.>-]
+++++++++[<<->>-]
<<.-.>.
Output:
1
2
3
4
5
6
7
8
9
10
Live demo:
Brainf**k print 1 to 10
Brainf**k Visualizer
TL;DR
-[>+<-----]>---<++++++++++<++++++++++[>>.+<.<-]>>---------.-.
Try it online!
END TL;DR
In order to program in BrainF**k, pretend like every program (even simple ones) will need to start out with a layout.
The pseudo-code for this would be something like:
Generate the character '0'
Move left and generate '\n'
Move left and generate the counter (10 numbers in this case)
Loop: Get back to the character '0', print it, increment it to '1', go to the newline, print it, go to the counter, and decrement it. End it when the counter is 0
Generate '1' and print it
Generate '0' and print it
However, the last two steps could be simplified to just:
Go back to the digit '9'
Decrement it until '1' and print
Decrement it until '0' and print
This saves a lot of time and bytes characters.
To generate the character '0', you generate the integer 48 (because that's it's ASCII value). To do this you can go to Esolangs' BF Constants. Looking up the number 48, we find -[>+<-----]>---
Our program so far is -[>+<-----]>--- to generate 0
Next, move left and generate \n (newline). We can use <++++++++++. Notice how it is completely plus signs. This is because there is not much room to reduce the character count at the number 10.
Our program so far is -[>+<-----]>---<++++++++++
Then, move left and generate the counter. We want the counter to be 10 to print numbers from 0 to 9. <++++++++++.
Our program so far is -[>+<-----]>---<++++++++++<++++++++++
After that, start the loop [. Go to the '0' >>, print it ., increment it +, go to the newline and print <., Go to the counter and decrement it, and end the loop when it is zero <-]. [>>.+<.<-]
Our program so far is -[>+<-----]>---<++++++++++<++++++++++[>>.+<.<-]
Finally, go to the '9' >>, decrement it until it is 1 and print ---------., and decrement it until it is 0 and print -.. ---------.-.
The program is finished.
++++++++++++++++++++++++++++++++++++++++++++++++ Let address 0 be the digit we want to print, starting with '0'
>++++++++++ Let address 1 be our newline character
>+++++++++ Let address 2 be our counter, starting at 9
[
- Decrement the counter
<<+. Increment the digit we want to print and print it
>. Print the newline
> Make sure we're at the counter again before we loop back
]
<< Move back to address 0
--------. Make address 0 '1'
-. Make address 0 '0'
Live demo
This is possible. Here's the code: ++++++++++>++++++++++[>+++++<-]>-.<<.>>+.<<.>>+.<<.>>+.<<.>>+.<<.>>+.<<.>>+.<<.>>+.<<.>>+.<<.>>--------.-. It could be shorter, however, it still accomplishes the same task. Brainf*** can theoretically perform any computation, as it is Turing complete. This is just one of those computations.
I suggest the following:
+++++++++>>++++++++[-<++++++>][-]>++++[-<++++++++>]<<<[->+.>.<<]>[-]+++++++[-<+++++++>]<.-.
It outputs 1 2 3 4 5 6 7 8 9 10.
We have this (each line is after the next cell-affecting instruction, which are + - .):
| C1 | C2 | C3 | C4 | Output |
+----+----+----+----+-----------------------+
| 0 | 0 | 0 | 0 | |
| 1 | 0 | 0 | 0 | |
| 2 | 0 | 0 | 0 | |
...
| 8 | 0 | 0 | 0 | |
| 9 | 0 | 0 | 0 | |
... (first loop)
| 9 | 48 | 0 | 0 | |
| 9 | 48 | 0 | 1 | |
| 9 | 48 | 0 | 2 | |
| 9 | 48 | 0 | 3 | |
| 9 | 48 | 0 | 4 | |
| 9 | 48 | 0 | 3 | | (enter second loop)
| 9 | 48 | 1 | 3 | |
| 9 | 48 | 2 | 3 | |
...
| 9 | 48 | 8 | 3 | |
| 9 | 48 | 8 | 2 | |
| 9 | 48 | 9 | 2 | |
...
| 9 | 48 | 16 | 2 | |
| 9 | 48 | 16 | 1 | |
| 9 | 48 | 17 | 1 | |
...
| 9 | 48 | 24 | 1 | |
| 9 | 48 | 24 | 0 | |
| 9 | 48 | 25 | 0 | |
...
| 0 | 48 | 32 | 0 | | (exit second loop)
| 8 | 48 | 32 | 0 | | (enter third loop)
| 8 | 49 | 32 | 0 | |
| 8 | 49 | 32 | 0 | 1 |
| 8 | 49 | 32 | 0 | 1_ | (underscores are spaces)
| 7 | 49 | 32 | 0 | 1_ |
| 7 | 50 | 32 | 0 | 1_ |
| 7 | 50 | 32 | 0 | 1_2 |
| 7 | 50 | 32 | 0 | 1_2_ |
| 6 | 50 | 32 | 0 | 1_2_ |
| 6 | 51 | 32 | 0 | 1_2_ |
| 6 | 51 | 32 | 0 | 1_2_3 |
| 6 | 51 | 32 | 0 | 1_2_3_ |
| 5 | 51 | 32 | 0 | 1_2_3_ |
| 5 | 52 | 32 | 0 | 1_2_3_ |
| 5 | 52 | 32 | 0 | 1_2_3_4 |
| 5 | 52 | 32 | 0 | 1_2_3_4_ |
| 4 | 52 | 32 | 0 | 1_2_3_4_ |
| 4 | 53 | 32 | 0 | 1_2_3_4_ |
| 4 | 53 | 32 | 0 | 1_2_3_4_5 |
| 4 | 53 | 32 | 0 | 1_2_3_4_5_ |
| 3 | 53 | 32 | 0 | 1_2_3_4_5_ |
| 3 | 54 | 32 | 0 | 1_2_3_4_5_ |
| 3 | 54 | 32 | 0 | 1_2_3_4_5_6 |
| 3 | 54 | 32 | 0 | 1_2_3_4_5_6_ |
| 2 | 54 | 32 | 0 | 1_2_3_4_5_6_ |
| 2 | 55 | 32 | 0 | 1_2_3_4_5_6_ |
| 2 | 55 | 32 | 0 | 1_2_3_4_5_6_7 |
| 2 | 55 | 32 | 0 | 1_2_3_4_5_6_7_ |
| 1 | 55 | 32 | 0 | 1_2_3_4_5_6_7_ |
| 1 | 56 | 32 | 0 | 1_2_3_4_5_6_7_ |
| 1 | 56 | 32 | 0 | 1_2_3_4_5_6_7_8 |
| 1 | 56 | 32 | 0 | 1_2_3_4_5_6_7_8_ |
| 0 | 56 | 32 | 0 | 1_2_3_4_5_6_7_8_ |
| 0 | 57 | 32 | 0 | 1_2_3_4_5_6_7_8_ |
| 0 | 57 | 32 | 0 | 1_2_3_4_5_6_7_8_9 |
| 0 | 57 | 32 | 0 | 1_2_3_4_5_6_7_8_9_ | (exit third loop)
+----+----+----+----+-----------------------+
Then cell C2 is set to 0 and used to set cell C1 to 49 (charater 1).
It prints C1, then removes one and prints it again, giving an output of:
1_2_3_4_5_6_7_8_9_10 (underscores are spaces)
It's for me the simplest program to print the integers from 1 to 10.
If you want each number to be on its own line, replace the >>>++++[-<++++++++>]<<< by ++++++++++.
Issue [SOLVED]: instead of printing 10 at the end, it prints :...
If the maximum capacity of character is 256 how to store character array of 1000?
is it possible to declare:
char s[1000];
Yes, it is certainly possible.
char s[1000];
You can think of 1000 as the "length" of the array and 256 as the "width". You get an array of 1000 chars. Each char is 8 bits (on the machine you're using, at least), and can therefore store 256 distinct values. (And, actually, it would probably be more appropriate to think of the "width" as being 8, not 256.)
Here is your array, with each box representing one char:
+---+---+---+---+---+---+---+---+- -+---+
s: | | | | | | | | | ... | |
+---+---+---+---+---+---+---+---+- -+---+
0 1 2 3 4 5 6 7 999
Or here it is showing the individual bits:
+---+---+---+---+---+---+---+---+- -+---+
s: | | | | | | | | | | | 7
+---+---+---+---+---+---+---+---+- -+---+
| | | | | | | | | | | 6
+---+---+---+---+---+---+---+---+- -+---+
| | | | | | | | | | | 5
+---+---+---+---+---+---+---+---+- -+---+
| | | | | | | | | | | 4
+---+---+---+---+---+---+---+---+- -+---+ bit
| | | | | | | | | ... | | 3 number
+---+---+---+---+---+---+---+---+- -+---+
| | | | | | | | | | | 2
+---+---+---+---+---+---+---+---+- -+---+
| | | | | | | | | | | 1
+---+---+---+---+---+---+---+---+- -+---+
| | | | | | | | | | | 0
+---+---+---+---+---+---+---+---+- -+---+
0 1 2 3 4 5 6 7 999
array index
Suppose we put a string in the array, either by calling strcpy:
strcpy(s, "Hello!");
or my initializing it when we declare it:
char s[1000] = "Hello!";
By bytes it looks like this:
+---+---+---+---+---+---+---+---+- -+---+
s: | H | e | l | l | o | ! |\0 | | ... | |
+---+---+---+---+---+---+---+---+- -+---+
0 1 2 3 4 5 6 7 999
Or by bits it looks like this:
+---+---+---+---+---+---+---+---+- -+---+
s: | 0 | 0 | 0 | 0 | 0 | 0 | 0 | | | | 7
+---+---+---+---+---+---+---+---+- -+---+
| 1 | 1 | 1 | 1 | 1 | 0 | 0 | | | | 6
+---+---+---+---+---+---+---+---+- -+---+
| 0 | 1 | 1 | 1 | 1 | 1 | 0 | | | | 5
+---+---+---+---+---+---+---+---+- -+---+
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | | | | 4
+---+---+---+---+---+---+---+---+- -+---+ bit
| 1 | 0 | 1 | 1 | 1 | 0 | 0 | | ... | | 3 number
+---+---+---+---+---+---+---+---+- -+---+
| 0 | 1 | 1 | 1 | 1 | 0 | 0 | | | | 2
+---+---+---+---+---+---+---+---+- -+---+
| 0 | 0 | 0 | 0 | 1 | 0 | 0 | | | | 1
+---+---+---+---+---+---+---+---+- -+---+
| 0 | 1 | 0 | 0 | 1 | 1 | 0 | | | | 0
+---+---+---+---+---+---+---+---+- -+---+
0 1 2 3 4 5 6 7 999
array index
And there are 993 spaces in the array left over.
[P.S. to nitpickers: Yes, those are ASCII codes, and no, character encoding is not specified by the C Standard. But I think we can safely assume that those are the codes the questioner would see.]
The 256 is the number of values in a single char (which is often an 8 bits byte, and 256 = 28).
(caveat, the C11 standard allows wider char-s, e.g. of 32 bits; but this is very uncommon)
A string is an array or a memory zone containing several char-s, and conventionally terminated by a zero byte.
You can have very big strings, notably using C dynamic memory allocation. For instance, on some computers
char*hugestring = malloc(1000000000);
can succeed. Then you could fill that billion-bytes string. On many computers, that malloc call would fail, and you always need to check the result of malloc, at least by following the above line with
if (!hugestring) { perror("malloc hugestring"); exit(EXIT_FAILURE); };
If you use malloc, don't forget to later call free (you need to have conventions about who is responsible for that); otherwise you have a memory leak. BTW the asprintf, strdup and open_memstream functions are very useful (but not available everywhere) to conveniently build dynamically allocated strings (internally malloc is used by them). Tools like valgrind are helpful to help detecting memory leaks.
You can also have arrays. If they are local variables (a.k.a. automatic variables) they generally sit in the call stack (unless the compiler optimized for them).
For example, using snprintf to safely fill a local buffer (without buffer overflow),
char buffer[100];
snprintf(buffer, sizeof(buffer), "x=%d, name=%s", x, name);
but it is unreasonable to have large call frames, so a local array should generally be less than a few hundred bytes (or perhaps a few thousands of them). The entire call stack is generally limited to one or a few megabytes. Details are system specific.
Be aware of character encoding issues. In 2017 read at least utf8everywhere.org and about Unicode.... so think of char as a byte (since some UTF-8 characters need several bytes, so take several char-s to be represented, hence on my Linux desktop strlen("être") is 5 and sizeof("être") is 6 since the accentuated ê letter is UTF-8 encoded in two bytes). You might use some library like libunistring.
Look also into some C reference.
You seem to misinterpret what you refer to as "capacity" of a char. char is an 8-bit value, which means it can range anywhere from 0000 0000b () to 1111 1111b (255).
This only refers to one individual value. This means you can write char c = 20;, but not char c = 1000;.
As such, this means that there are 256 different possible values for a single char.
Arrays are a different concept: An array stores multiple values of one specific type - such as an array of characters.
To answer you question: Yes, you can store 1000 char values in an array, like char s[1000] as Steve Summit suggested.
Naturally, if you have 1000 chars, this will mean there will be duplicates (since there are only 256 unique characters possible).
typedef struct arg_struct {
struct GPU_FFT *fft;
struct GPU_FFT_COMPLEX *base;
float **input;
float *output;
int number;
} arg_struct;
...
arguments[0].input = **Queue;
arguments[1].input = *(*(Queue)+QueueSize[0]);
My multidimensional array is Queue[2][1025]. I am trying to pass Queue[0][0] and Queue[1][0] into my arguments structure. It gives me "error: incompatible types when assigning to type ‘float **’ from type ‘float’" error. As a rookie programmer, I've tried so many variations but still couldn't figure out how to pass them.
By the way, QueueSize[0] is an integer which has value of 1025.
You can solve your problem very easily, by making the input member a simple pointer:
float *input;
Then you can make each pointer point to the corresponding array of Queue:
arguments[0].input = Queue[0];
arguments[1].input = Queue[1];
Be careful though, the lifetime of Queue must be at least as long as the lifetime of arguments. If Queue goes out of scope then the pointers will be stray, and can no longer be used. If Queue can go out of scope then you need to create full arrays of (or allocate memory for) the input member, and copy the contents into that memory.
There is big difference between 2d array and pointer to pointer.
In your struct is pointer to pointer, so you have to init it like
arguments[0].input = malloc(sizeof(float *) * num_of_rows);
for (int i = 0; i < num_of_rows; i++)
{
arguments[0].input[i] = malloc(sizeof(float) * num_of_cols);
}
Dont forget to free all the allocated memory. You can use valgrind for checking memory leaks.
2D array is sequence of bytes in memory
0 1 2 3
+---+---+---+---+
| 0 | 0 | 0 | 0 | 0 // begins on address 1000
+---+---+---+---+
| 0 | 0 | 0 | 0 | 1 // begins on address 1004
+---+---+---+---+
| 0 | 0 | 0 | 0 | 2 // begins on address 1008
+---+---+---+---+
| 0 | 0 | 0 | 0 | 3 // begins on address 1012
+---+---+---+---+
while array of pointers, where every pointer can point to another part of memory
0 1 2 3
+---+---+---+---+
| * | * | * | * |
+---+---+---+---+
| | | |
| | | | 0 1 2 3
| | | | +---+---+---+---+
| | | -> | 0 | 0 | 0 | 0 | // begins on address 1000
| | | +---+---+---+---+
| | -----> | 0 | 0 | 0 | 0 | // begins on address 2
| | +---+---+---+---+
| ---------> | 0 | 0 | 0 | 0 | // begins on address 3045
| +---+---+---+---+
-------------> | 0 | 0 | 0 | 0 | // begins on address 128
+---+---+---+---+