Ask about char in array - c

example
char names[2][5] = {"john","boy"};
I want to ask about char 2 dimension array in c, in [2] i mean, it's explaining about total element of array, and [5] i mean, it's explaining about length of character in array
So, is it true how to use array 2 dimension in c ?
Sorry for my bad english

names is an array of two elements, each element is in turn an array of five elements.
And you use each array like you would any other. So the firs element of names is names[0], the second is names[1]. Then the first element of names[0] is names[0][0], the second names[0][1], etc.
Also, because each element of names is an array, and each of those two arrays are initialized as null-terminated strings, you can use names[0] and names[1] like any other string.

A multidimensional array is an array elements of which are in turn arrays.
Let's consider your declaration
char names[2][5] = {"john","boy"};
You can introduce a type alias like
typedef char T[5];
so the name T is an alias for the type char[5].
Now your initial declaration may be rewritten like
T names[2] = {"john","boy"};
That is you have an array of two elements which of them is in turn an array of the type char[5].
String literals are also have types of character arrays. For example the string literal "John" can be represented like
char john[5] = { 'J', 'o', 'h', 'n', '\0' };
elements of a string literal are used to initialize a corresponding character array.
So you array is initialized like
char names[2][5] = { { 'J', 'o', 'h', 'n', '\0' }, { 'b', 'o', 'y', '\0', '\0' } };
If a string literal contains less elements than the number of elements of the initialized array then all other elements of the array that have no an explicit initializer will be zero-initialized.

Consider a table of 2 * 5, where you get 2 rows, each of 5 columns. Here 2 dimensional array contains 2 rows i.e 2 char*. Each row is of size 5
Outputs:
names[0][0] = 'j'
names[1][0] = 'b'
name[0] = "john"
name[1] = "boy"

char names[2][5] = {"john","boy"};
names is a multi-dimensional char array with the height of 2 and the width 5:
__________________________________________________________________
│ j │ o │ h │ n │ \0 │ // 5 char elements, 1.dimension
│names[0][0]│ names[0][1]│ names[0][2]│ names[0][3] │ names[0][4] │
│___________│____________│____________│_____________│______________│
│ b │ o │ y │ \0 │ \0 │ // 5 char elements, 2.dimension
│names[1][0]│ names[1][1]│ names[1][2]│ names[1][3] │ names[1][4] │
│___________│____________│____________│_____________│______________│
Sorry, for the simple example but this might help you.

Related

Can lldb display char * / strings in structs more efficiently?

lldb has a habit to show me strings in a very spread out manner, which is a little annoying but not a show stopper. But maybe someone already knows how to make it a bit more efficient with its display size:
Example:
(lldb) p *tq
(taskq_t) $14 = {
tq_name = {
[0] = 's'
[1] = 'y'
[2] = 's'
[3] = 't'
[4] = 'e'
[5] = 'm'
[6] = '_'
[7] = 't'
[8] = 'a'
[9] = 's'
[10] = 'k'
[11] = 'q'
[12] = '\0'
[13] = '\0'
[14] = '\0'
[15] = '\0'
[16] = '\0'
[17] = '\0'
[18] = '\0'
[19] = '\0'
[20] = '\0'
[21] = '\0'
[22] = '\0'
[23] = '\0'
[24] = '\0'
[25] = '\0'
[26] = '\0'
[27] = '\0'
[28] = '\0'
[29] = '\0'
[30] = '\0'
[31] = '\0'
}
tq_lock = {
Would prefer:
(lldb) p *tq
(taskq_t) $14 = {
tq_name = {
"system_taskq\0"
}
tq_lock = {
Or similar - as in, a string. As it gets quite long when it is char path[MAXPATH].
Showing all the elements is the natural view for an array, and since there's no guarantee that a char array is actually a null terminated string, even printing char arrays as an array is a reasonable default. But as you observe, if you know the array holds a null terminated string you really do want to print it more compactly.
Fortunately, lldb has a system for providing "alternate" views of data objects. That's why, for instance you see:
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
frame #0: 0x0000000100003f0b has_char`main at has_char.c:8
5 {
6 char *myStr = "some string here";
7 char myArr[20] = {'s', 'o', 'm', 'e', ' ', 's', 0};
-> 8 return strlen(myStr) + strlen(myArr);
^
9 }
Target 0: (has_char) stopped.
(lldb) v myArr
(char [20]) myArr = "some s"
By default lldb presents char[NN] arrays as null terminated strings.
That's done using lldb's "summary formatters". There's a bunch more information about them here:
https://lldb.llvm.org/use/variable.html
You can find out how a particular variable gets its formatting, which is sometimes useful when you're looking for something to copy, with:
(lldb) type summary info myArr
summary applied to (char [20]) myArr is: `${var%s}` (hide value) (skip pointers)
The summaries are registered by a type name or type regular expression, and then applied to any value of that type when printing it. They also follow typedef chains so the same summary will be provided for variables whose type is a typedef of a registered type. What is the type of tq_name, it looks like it is just a char array? I'm a little surprised you had to do anything here...
Anyway, no worries, you can always add one explicitly for your type.
The command for that is:
(lldb) type summary add -s ${var%s} -p -v TypeNameOfTQ
-s is the summary string, see the docs cited above for more on that.
-p because you don't want to format a char [10]* this way.
-v because you explicitly don't want to see the elements one by one - which is the natural value of the array.

Understanding array manipulation pointers syntax in C

I have a struggle understanding a syntax of pointers, for example,
I have this code below:
void main(void)
{
char arr[][10] = {"It's", "wide", "and", "wonderful"};
printf("%c", (*arr)[3] - 1);
printf("%c", *arr[2] + 3);
}
I have no clue why it prints 'r' and 'd' like what's the whole process, I would kindly like an explanation.
This is obfuscation: code deliberately written to confuse.
*arr gives the first item (array) in your 2D array. At index 3 you find 's'. ASCII code for 's' - 1 = 'r'.
In *arr[2], the [] operator takes precedence, giving you the item at index 2 in your 2D array ("and"). * gives the contents of the first item (character) in that array, 'a'. ASCII code for 'a' + 3 = 'd'.
(Please note that arithmetic on symbol table values is not portable code. Only the digits 0 to 9 are guaranteed by the C standard to be placed adjacently in the symbol table.)
I'll break up the expressions (*arr)[3] - 1 and *arr[2] + 3 in order of precedence.
Expression (*arr)[3] - 1:
arr → {"It's", "wide", "and", "wonderful"}
(*arr) → "It's"
(*arr)[3] → 's'
(*arr)[3] - 1 → 'r'
Notice here two things: *arr is equivalent to arr[0], and you can perform arithmetic on a char, operating on the numeric value representing the character.
Expression *arr[2] + 3:
arr → {"It's", "wide", "and", "wonderful"}
arr[2] → "and"
*arr[2] → 'a'
*arr[2] + 3 → 'd'
The news here is that arr[] takes precedence over *arr, that is why the parenthesis is important in the first expression.
void main(void)
{
char arr[][10] = {"It's", "wide", "and", "wonderful"};
printf("%c", (*arr)[3] - 1); // arr[0][3] == the 4th char of the 1st string - 1 = s - 1 = r
printf("%c", *arr[2] + 3); // arr[2][0] == the 1st char of the 3rd string + 3 = a + 3 = d
}
in first case (*arr)[3] - 1
(*arr) gives us pointer to the first element of array: "It's"
(*arr)[3] gives us fourth element of "It's" which is: 's'
subtracting 1 from 's' gives us 'r'
in second case *arr[2]:
arr[2] gives us pointer to the third element of array: "and"
*arr[2] gives us first character of "and" which is 'a'
adding 3 to 'a' gives us 'd'
For (*arr)[3] - 1:
arr when treated like a pointer: the address of the first element. In this case, it is the address of "It's"
(*arr): dereferencing arr, aka "It's". And it's a char*
(*arr)[3]: the 4th character of "It's". The type is char
(*arr)[3] - 1: char can be used as a integer, so subtracting a char is subtracting its ASCII code. The value is 'r'
For *arr[2] + 3:
arr[2]: the 3rd element of arr (treated as an array), which is "and". The type is char*
*arr[2]: dereferencing "and", so 'a'
*arr[2] + 3: again ASCII code, its value is 'd'
Arrays used in expression are implicitly converted (with rare exceptions) to pointers to their first elements.
So if an array declared like this
char arr[4][10]
then this declaration you may rewrite like
char ( arr[4] )[10]
and in an expression the array designator is converted to pointer to its first element
char ( *p )[10]
So in this expression
(*arr)[3] - 1)
arr is converted to the type char ( * )[10] and points to the first string stored in the array. Applying the operator * you get the first sub-array (first string) that has the type char[10].
Applying the subscript operator you get the fourth character in the string that is equal to 's'. Now subtracting 1 you get the character 'r'.
In the second expression
*arr[2] + 3
that can be equivalently rewritten like
*( arr[2] ) + 3
you at first get the third sub-array of the array that is the sub-array with the string "and". This sub-array has the typechar[10]. Dereferencing the array designator (that is implicitly converted to pointer to its first element) you get the first character of the string that is'a'Adding to the character 3 you get the character'd'`.
The difference between the expressions is that in the first case you are dereferecing the array designator getting pointer to the first element and then applying the subscript operator for one-dimensional character array. In the second case you are first applying the subscript operator again getting one-dimensional array and then dereferencing the array designator that is implicitly converted to pointer to its fir element.
You should understand that if you have an array like for example
char s[] = "Hello";
then the expression *sis equivalent to *( &s[0] ) that is to s[0].
The expression *arr[2] is equivalent1),2) to arr[2][0] -
*arr[2] -> *(arr[2]) -> *((arr[2]) + 0) -> arr[2][0]
The expression (*arr)[3] is equivalent2) to arr[0][3] -
(*arr)[3] -> (*(arr + 0))[3] -> arr[0][3]
arr[0][3] represents 3rd character in first array which is s and arr[2][0] represents 0th character in third array which is a
The 2D array arr:
Array arr:
[0] = {
[0] = 'I'
[1] = 't'
[2] = '''
[3] = 's' ---> (*arr)[3], substrat 1 from s ==> r
[4] = '\0'
[5] = '\0'
[6] = '\0'
[7] = '\0'
[8] = '\0'
[9] = '\0'
}
[1] = {
[0] = 'w'
[1] = 'i'
[2] = 'd'
[3] = 'e'
[4] = '\0'
[5] = '\0'
[6] = '\0'
[7] = '\0'
[8] = '\0'
[9] = '\0'
}
[2] = {
[0] = 'a' --> *arr[2], add 3 to a ===> d
[1] = 'n'
[2] = 'd'
[3] = '\0'
[4] = '\0'
[5] = '\0'
[6] = '\0'
[7] = '\0'
[8] = '\0'
[9] = '\0'
}
[3] = {
[0] = 'w'
[1] = 'o'
[2] = 'n'
[3] = 'd'
[4] = 'e'
[5] = 'r'
[6] = 'f'
[7] = 'u'
[8] = 'l'
[9] = '\0'
}
}
1) The precedence of [] operator is higher than unary * operator.
2) C Standards#6.5.2.1
The definition of the subscript operator [] is that E1[E2] is identical to (*((E1)+(E2)))..
First, let's note that *arr[2] is equivalent to *( arr[2] )
Secondly, keep in mind there is no difference between *(a + i) and a[i].
Thirdly, if there's no difference between *(a + i) and a[i], there's no difference between *a and a[0].
So,
(*arr)[3] === ( *( arr + 0 ) )[3] === arr[0][3]
The above produces the fourth character of the first string.
*arr[2] === *( arr[2] ) === *( arr[2] + 0 ) === arr[2][0]
The above produces the first character of the third string.

How do I give best2 this assignment as an array?

Assume that two parallel arrays have been declared and initialized : healthOption an array of type char that contains letter codes for different healthcare options and annualCost an array of type int . The i-th element of annualCost indicates the annual cost of the i-th element of healthOption. In addition, there is an char variable , best2.Write the code necessary to assign to best2 the health option with the lower annual cost, considering only the first two healthcare options.
Thus, if the values of healthOption are 'B', 'Q', 'W', 'Z' and the values of annualCost are 8430, 9400, 7050, 6400 your code would assign 'B' to best2 because 8430 is less than 9400 and is associated with 'B' in the parallel array . (We ignore 'W' and 'Z' because we are considering only the first two options.)
int[] annualCost = new int[] { 8430, 9400, 7050, 6400 }
char[] healthOption = new char[] { 'B', 'Q', 'W', 'Z' };
int[] annualCostbest2 = new int[] { annualCost[0],annualCost[1] };
//Get Minimum value from Your array
int min = annualCostbest2.Min();
//Take index of lowest price value
int index = Array.IndexOf(annualCostbest2, min);
//Get value from your 2nd array
char best2 = healthOption[index];

Check for a word in a dictionary in C

I have a project in which I have a file (.dic) with many words with different sizes. And another file (.pal) with some words. For each word of the .pal file, I have to find its position in a list of words with the same number of words, ordered alphabetically from the .dic file.
For example,
in the .dic file:
car
banana
dog
flower
tar
So the dictionary would be something like:
3 letters: [car->dab->dog->tar]
6 letters: [banana->flower]
in the .pal file:
dog
flower
So the output would be:
dog in position 3
flower in position 2
My question is: What is the best data structure to implement this in C, so that it takes the least memory and time?
I was thinking of having a matrix in which each the first index (index1) corresponds to the number of letters in the word, and the second index (index2) corresponds to the first letter of the word I'm looking for. Each element of that matrix is a list of words with index1 letters and starting in letter index2.
Example:
| A | B | C | .....
_______________
1|list|list|list|
2|list|....|....|
3|...
.
.
So "dog" would be in a list inside matrix[3][D].
Problem 1: the matrix will have hole if there aren't words with all different number of letters or different first letters -> too much memory wasted?
Problem 2: to know the position I asked before I would have to sum up the number of elements of each list before the one I'm using.
Example: "dog" position would be
number of element in list [3][A]+number of element in list [3][B]+number of element in list [3][C]+"dog" position in the list
So when I inserted a word in a list, I would have to update the numbers of elements of the lists in the next matrix elements. -> time consuming?
So what do you think of this method? Do you have better ideas?
What is the best data structure to implement this in C, so that it takes the least memory and time?
It's difficult to get both least memory and least time. If you want to keep memory usages as low as possible, you'll need dynamic memory allocation which is expensive when considering time.
To get low memory usage, you could go for the following data structure:
#define MAX_WORD_LEN 50
char** dic[MAX_WORD_LEN];
You use it like this:
index 0: -----> char*, char*, char*, ... // Words with length 1
| | |
| | ------> string (i.e. char, '\0')
| |
| ------> string (i.e. char, '\0')
|
------> string (i.e. char, '\0')
index 1: -----> char*, char*, ... // Words with length 2
| |
| ------> string (i.e. char, char, '\0')
|
------> string (i.e. char, char, '\0')
This allows you to store a variable number of words for each length and you don't allocate more memory than needed for each string. It is like a matrix but the benefit is that each row can have different number of columns.
You will however need quite some dynamic memory handling, i.e. malloc, realloc and strdup.
To save some execution time you should grow the "char*, char*, char*, ..." array by some N larger than 1 and set the unused entries to NULL. That will save a lot of realloc but you'll need to keep track on the number of allocated elements in each row. That could call for something like:
struct x
{
char** data;
int number_allocated;
}
#define MAX_WORD_LEN 50
struct x dic[MAX_WORD_LEN];
If memory usage is real hot, you can avoid the "char*, char* ..." array and just use one big char array for each word length. Like:
index 0: -----> 'a', '\0', 'I', '\0', ...
index 1: -----> 'b', 'e', '\0', 't', 'o', '\0', ....
You can do this because all words in a char-array has the same length.
In this case you would have something like:
struct x
{
char* data;
int bytes_allocated;
int number_of_words;
}
#define MAX_WORD_LEN 50
struct x dic[MAX_WORD_LEN];

Win32 API working with arrays

I'm beginner of programmer. I not understande why can't copy some script from array to another one.
char array1[11];
char array2[2];
array1 = {'255 105 85'};
array2[0] = array1[0];
array2[1] = array1[1];
array2[2] = array1[2];
MessageBox(hwnd,array2,"mes",NULL);
I was get "5" instead of "255".
I using the code::blocks with GCC complier.The project created with win32 frame based.
Somebody has idea what cause the problem?
The following construct is not allowed in C:
array1 = {'255 105 85'};
Instead you might consider using the static array initialization like this:
char array1[11] = {255, 105, 85};
This will fill the array1 with 3 specified values and leave all the other elements set to 0 (i.e. elements starting with index 3 and ending with index 10).
It's rather surprising, why the compiler didn't issue a syntax error in your case
updated:
Please also note that you are manipulating with individual characters when you have an expression like this array1[2]. If you want to operate on strings (i.e. have 3 separate strings for the numbers you have specified), you will have to declare something like this:
char *array1[3] = {
"255",
"105",
"85"
};
char *array2[3];
array2[0] = array1[0];
array2[1] = array1[1];
array2[2] = array1[2];
Thus you will have an array of strings. Each entry of array1 will contain a pointer (address) of the memory where string "255" is located (please note that "255" is an array comprising 4 chars: '2', '5', '5', '\0').
Array1 should be declared like this:
char array1[] = {0x255, 0x105, 0x85};
single quotes are for single chars in ascii, like 'a' or '6' or '!'.
Also, array2 is of length 2, but you are assigning a value to the third value (array2[2]). This is probably an error.

Resources