I'm stuck on some homework which isn't graded (its meant for practice).
I have to create a function called find_name that takes 2 arguments. The first argument is a 2D array of names (strings), and the second is a character string which is used to find the name in the 2D array, the function must return 1 if found else 0.
When i call the function (which is empty right now), I get this warning: passing argument 1 of 'find_name' from incompatible pointer type
Here is the important bits.
In Main
char strNameList[][2] = { { "Luca","Daniel"} ,{"Vivan","Desmond"},{"Abdul","Justin"}, {"Nina","Marlene"},{"Donny","Kathlene"} };
char strFindName[] = "\0";
printf("Please enter a name to look for: ");
gets(strFindName);
nSearch = find_name(strNameList, strFindName);
The Function
int find_name(char strNameList[][2], char strLookUp[])
I'm new to C (I'm a student), and I'm completely confused about strings (string arrays etc).
I'm assuming you want a 2D array of char pointers. Your declaration of strNameList is incorrect in both locations in your program. You have:
char strNameList[][2] = { { "Luca","Daniel"} ,{"Vivan","Desmond"},{"Abdul","Justin"}, {"Nina","Marlene"},{"Donny","Kathlene"} };
But char[][N] is declaring a 2D array of chars, not char* Therefore you're being warned by the compiler you're assigning a raft of pointer values to items of type char
Change both your declarations (your variable and your function parameter) to:
const char *strNameList[][2]
which declares an array of unknown length of arrays of two char*, which now matches your initialization lists. Also, the const is added because (a) I'm assuming you are not planning on modify that name list in your function, and (b) writable string literal declarations assigned to char* via initializer is undefined behavior in C, and officially deprecated in C++, so you should not be using it regardless. Likewise, your lookup-name is probably not being modified either, so also declare it const.
Result:
const char * strNameList[][2] = {
{"Luca","Daniel"} ,
{"Vivan","Desmond"},
{"Abdul","Justin"},
{"Nina","Marlene"},
{"Donny","Kathlene"}
};
and in your function:
int find_name(const char * strNameList[][2], const char strLookUp[])
Last but certainly not least, unless you have a crystal ball your find_name() function has no way of knowing with the given information how many names are in the name list being passed. I'd rather you see this now rather than wonder what happened later. you need to either (a) terminate the list with a token-value that find_name() knows about, or (b) pass the number of names in the list to find_name(). To each their own, but I prefer the latter of these:
int find_name(const char * strNameList[][2], size_t nNameListSize, const char strLookUp[])
and invoke it on your caller side by:
find_name(strNameList, sizeof(strNameList)/sizeof(strNameList[0]), strFindName)
Do it this way:
#define STOPPER_NAMELIST NULL
char * strNameList[][2] = {
{ "Luca","Daniel"},
{"Vivan","Desmond"},
{"Abdul","Justin"},
{"Nina","Marlene"},
{"Donny","Kathlene"}
{STOPPER_NAMELIST, STOPPER_NAMELIST}
};
size_t sizeNameList(const char * strNameList[][2])
{
size_t size = 0;
while ((strNameList[size][0] != STOPPER_NAMELIST) &&
(strNameList[size][0] != STOPPER_NAMELIST))
++ size;
return size;
}
int find_name(char * strNameList[][2], char strLookUp[])
{
size_t size = sizeNameList(strNameList);
...
}
...
nSearch = find_name(strNameList, strFindName);
This approach uses an open array ([]) of char * arrays with 2 entries.
Update:
You could add a stopper element to the array carring the names, then there is no need to pass around the array's size along with array itself, as the size could alway be determined by scanning the array members until the stopper is found.
Your function find_name() is looking for a 2-D array of characters ie:
char arr[][2] = { { 'a', 'b'}, ...
if you want to make them strings you need:
char *arr[][2] = { {"John", "Smith"}, ...
Then in the function parameter list you need:
void find_name(char *something[][2])
{
printf("first name: %s, second name: %s\n", something[0][0], something[0][1]);
And in your main() function call it just by:
find_name(arr);
Related
This question already has answers here:
C sizeof a passed array [duplicate]
(7 answers)
Closed 2 years ago.
Is there a way I could get the length of an array inside a function? I need to find the size of an array, however it is defined in the main function and I cannot pass the array size as an argument as I cannot change the main function. So is there any way to find it through the function?
The array's max size is set to be roughly 100, however the actual input will be anywhere between size 1 - 20. So I can't really take the max size approach either.
No, arrays always decay to pointers when passing into functions so you must pass the length in if you want the function to know the size. With some preconditions you have multiple ways to do that without an additional parameter:
Add a null/zero/whatever special parameter at the last, similar to a null-terminated char array. This is only possible if you really know there's a unique value that never appears in the value list to put at the final position. This method is actually very common in Linux system calls, for example the exec family
char *args[] = { "Hello", "C", "Programming", NULL /* ends the array */ };
execv("./hello", args);
Add a length prefix at the beginning
void my_function(int array[])
{
int length = array[0];
int* data = &array[1];
// operate on data[];
}
int my_data[LENGTH + 1] = { LENGTH, /* values */ };
my_function(my_data);
Pascal also uses length-prefixed string, so its string is limited to only 255 characters with a 1-byte length. But this can be fixed by using a bigger length
A variation of this is BSTR in Windows where the pointer points to the actual data instead of start of the struct
typedef struct MY_ARRAY
{
int32_t length;
my_type* data; // array of the desired type
} my_array;
void my_function(my_type array[])
{
int length;
memcpy(&length, (char*)array - sizeof(int32_t), sizeof(int32_t));
// operate on array[];
}
my_type data_list[] = { /* some data */ };
my_array my_data = { LENGTH, data_list };
my_function(my_data.data);
if the function is declared for example like
void f( T a[] );
where T is some type specifier then the function deals with a pointer to the type T. That is the above declaration is equivalent to the following declaration
void f( T *a );
and the both declare the same one function.
So the only way to calculate the number of actual elements in the array pointed to by the pointer is to introduce a sentinel value that will differ from values of actual elements of the array.
For example a character array can have such a sentinel value like '\0' that is when a character array contains a string.
An array of strings can have as a sentinel value either an empty string "" or depending on how it is declared (for example as an array of element type char *) the sentinel value can be NULL.
For integer arrays you have yourself to select an appropriate value as a sentinel value. For example if actual elements are non-negative then the sentinel value can be set to -1.
You could include a for loop with a counter to see how many variables there are before the the next line.
int counter(int array[100]) {
int counter = -1;
for (i = 0; array != '\0'; i++) {
counter = counter + 1;
}
return counter;
}
and then in the main section
int arraysize = counter();
I have two arrays of the alphabet in the following format:
const char plain[26] = {'a','b',....'y','z'} // this is the the full alphabet
const char crypt[26] = {'i','d',....'m','x'}; // this is the the alphabet scrambled
The order of the alphabet in both arrays can change depending on input. This change happens in the main function.
The purpose of this is to match the letters of the string to the second, like an encryption. I compare characters to array values. So it would kind of look like this (simplified)
text[3] = 'yes';
changed[3];
if(text[0] == plain[25]){ //would be done under a for loop so 25 would be a changing integer value
changed[0] = [crypt[25];
}
My code works under perfectly under the main function. I wanted to mention my purpose like this because I was having previous problems simply due to the type of array and formatting. And since the array is moved outside, I will probably/am running into those problems again.
Now I want to make the arrays global. The actual encryption happens in a function that does not take the arrays as a variable. But I want the function to have access to them.
Here's what it looks likes right now
const char plain[26];
const char crypt[26];
int maint(void){
const char plain[26] = {'a','b',....'y','z'} \\values get changed here
const char crypt[26] = {'i','d',....'m','x'} \\and here
While this provides no errors, I dont get an output, I believe the other functions are using a blank array instead of the changed one (if the change even worked).
I've tried different array types, I believe the issue is in initialization or giving the array values.
Edit: To clarify, the two arrays can be in any order. A text file will randomize the order can give it to me in the format:
b,r
m,o
l,s
...
...
...
Both cases the alphabet is randomized. Where the first column would correspond to the first array (plain), second would be to second array (crypt).
If there's a way to read by columns and store in the format
plain = 'bml...'; \\whole alphabet randomized
crypt = 'ros...'; \\whole alphabet randomized
That would also work.
The plain and crypt you have in main aren't the same as the global ones. Since you declare them again, they're new ones that are only visible in main. Thus you're not changing the global ones.
Instead, only declare them once globally and do assignment in the main function:
char plain[26];
int main(void) {
memcpy(plain, "abcdefghijklmnopqrstuvwxyz", 26); //values get changed here
return 0; // indicate successful program execution
}
Also note that there are some syntax errors in
const char plain[26] = {'a','b',....'y','z'} \\values get changed here
Comments start with //, not \\, and you need a ; after a statement. Also, the int main should return an int in C.
Of course, if you don't need to actually change the memory and only assign it to predefined sets of characters, you can do it like this:
const char *plain;
int main(void) {
plain = "abcdefghijklmnopqrstuvwxyz";
return 0;
}
This way you can still read from it with syntax like plain[5], but you can't assign to it with, say plain[5] = 'a';.
Remove "const char" before plain and crypt arrays in main function to see the actual issue.
“Const Char” before plan and crypt arrays actually declare two new local char array constants with same name. As “const” char array can only be initialized at the declaration time therefore initialization in main does not throw error because they are not same global conts arrays.
Instead of using const use Const pointer as suggested in below answer
Another way to look at it is that plain and crypt will both decay to pointers on access (subject to the exceptions in) C11 Standard - 6.3.2.1 Other Operands - Lvalues, arrays, and function designators(p3). So why not just use global pointers to begin with that can then be reassigned as needed throughout your code?
This provides the flexibility of assignment from (1) string literals; (2) constant arrays; or (3) from compound literal initializers. You can #define a constant for the size (number of characters) plain and crypt point to.
For example:
#include <stdio.h>
#define NC 3 /* number of chars (26 for you) */
const char *plain, *crypt; /* global pointers */
void prnchars (const char *arr)
{
for (int i = 0; i < NC; i++)
putchar (arr[i]);
putchar ('\n');
}
int main (void) {
plain = "abc"; /* assigning literals */
crypt = "def";
prnchars (plain);
prnchars (crypt);
crypt = "ghi"; /* reassign at will */
prnchars (crypt);
const char foo[] = "jkl"; /* constant arrays */
crypt = foo;
prnchars (crypt);
crypt = (const char[]){'m', 'n', 'o'}; /* compound literals */
prnchars (crypt);
return 0;
}
Example Use/Output
$ ./bin/global_ptr
abc
def
ghi
jkl
mno
It's just another way of looking at the problem.
I have an array of names stored in char *namelist[]. When I pass it to a function, I'm unable to display all of the names in the namelist:
int ReadListOfName(const char* names[])
{
//Note: I always get the len = 1
// Anyway I can get total items in names
int len = sizeof(names)/sizeof(char*);
for (i=0; i<len; i++)
printf("%d-%s\n",i,names[i]);
return 0;
}
int main(void)
{
const char* names[] = {"a","b","c"};
ReadListOfName(names);
return 0;
}
What's the problem?
int len = sizeof(names)/sizeof(char*);
This doesn't get you the number of elements, sizeof doesn't do what you want on pointers. You have to pass the length as an additional argument to the function. Also discussed in this C FAQ. You could try:
int ReadListOfName(const char* names[], size_t len)
/* ... */
ReadListOfName(names, sizeof(names)/sizeof(names[0]));
int ReadListOfName(const char* names[])
In this names essentially becomes char ** rather than char * [] as defined your main.
You'll need to pass in another argument to ReadListOfName specifying the length of the array or have a terminating value in your array like argv does. When passed to a function, an array will decay to a pointer; a char*[] will decay to a char**, as you're passing the address of the first element in the array. Therefore your function is in fact interpreted as:
int ReadListOfName(const char **names)
And you're actually equating sizeof(char**)/sizeof(char*), which won't give you the number of elements in the array (it'll probably give you 1).
Add a length argument and then just calculate len before passing it ReadListOfName.
Note that rather than dividing sizeof(names) by sizeof(char*) to get the number of elements in the array, you can instead divide by sizeof(*names), and you wouldn't need to worry about changing char* if you change the type of the elements in names:
int len = sizeof(names)/sizeof(*names);
As the other answers already explain what happens to the array reference when passing it to the function, please find an approach to solve the issue without adding another parameter to the method printing the names.
You might like to add a stopper element to your list like so:
#include <stdio.h>
int ReadListOfName(const char ** names)
{
for (int i=0; names[i]; i++)
printf("%d-%s\n",i,names[i]);
return 0;
}
int main(void)
{
const char* names[] = {"a","b","c", NULL}; /* Please note the additional, last element. */
ReadListOfName(names);
return 0;
}
The essential difference of this approach to the one passing two arguments discribing the list names[], is the fact that its use is less error-prone as the information of the list's size is drawn from the list itself, but from a second independently provided value.
you should pass an additional argument which will explicitly mention the length of the array. and where you are initializing setup some MACRO to fiddle with sizeofs.
sizeof(AnyPointer) gives word size. In case of 32-bit OS, 4 will be returned. similarly 8 will be returned in 64-bit machine.
So sizeof(char*) == sizeof(float*) == sizeof(int*) is true.
If your OS is 32-bit,
sizeof(names) will be 4.
sizeof(char*) also 4.
Obviously you will get len = 1.
I am new to C, and things are different in C than in any other language I've learned. In my homework I want to create an array of chars which point to an array of chars, but rather than make a multidimensional char array, I figure I'd have more control and create char arrays and put each individual one into the indexes of the original char array:
char keywords[10];
keywords[0] = "float";
The above example is to clarify and a simple case. But my question is due to the research I've been doing, and I am confused about something. Normally this would work in other languages, but in C it would be:
char *keyword[10];
keywords[0] = "float";
But when I want to send it through a function, why is this necessary:
void function(char **keyword); //function prototype
Wouldn't just passing the array pointer be enough?
It looks like you're confused by the double stars in
void function(char ** keyword);
The double stars just means that this function expects you to pass a pointer to a pointer to a char. This syntax doesn't include any information about the fact that you are using an array, or that the char is actually the first char of many in a string. It's up to you as the programmer to know what kind of data structure this char ** actually points to.
For example, let's suppose the beginning of your array is stored at address 0x1000. The keyword argument to the function should have a value of 0x1000. If you dereference keyword, you get the first entry in the array, which is a char * that points to the first char in the string "float". If you dereference the char *, you get the char "f".
The (contrived) code for that would look like:
void function(char **keyword)
{
char * first_string = *keyword; // *keyword is equivalent to keyword[0]
char first_char = *first_string; // *first_string is equivalent to first_string[0]
}
There were two pointers in the example above. By adding an offset to the first pointer before dereferencing it, you can access different strings in the array. By adding an offset to the second pointer before dereferencing it, you can access different chars in the string.
char *keyword[10];
keyword is an array 10 of char *. In a value context, it converted to a pointer to a char *.
This conversion is a part of what Chris Torek calls "The Rule":
"As noted elsewhere, C has a very important rule about arrays and pointers. This rule -- The Rule -- says that, in a value context, an object of type ‘array of T’ becomes a value of type ‘pointer to T’, pointing to the first element of that array"
See here for more information: http://web.torek.net/torek/c/pa.html
The C-FAQ also has an entry on this array to pointer conversion:
Question 6.3: So what is meant by the "equivalence of pointers and arrays'' in C?
http://c-faq.com/aryptr/aryptrequiv.html
In C, you can't really pass array to a function. Instead, you pass a pointer to the beginning of the array. Since you have array of char*, the function will get a pointer to char*, which is char**.
If you want, you can write (in the prototype) char *keyword[] instead of char **keyword. The compiler will automatically convert it.
Also, in C you can dereference pointers like arrays, so you loose almost nothing with that "converting to pointer".
If you want to
void function(char **keyword);
Andy, think about that an array is just a pointer(to the beginning of the array), that's why you write:
void function(char **keyword);
Because you have create an array to char pointers.
If it's easier to understand try:
void function(char *keyword[]);
But it's more C standard to use the first one, though if you use a C++ compiler won't really matter.
Here is the answer.
#include<stdio.h>
int main(void)
{
char *CharPtr[3];
char a[4]="abc";
char b[4]="def";
char c[4]="ghi";
CharPtr[0]=a;
CharPtr[1]=b;
CharPtr[2]=c;
printf("\n content of CharPtr[0] =%s",CharPtr[0]);
printf("\n content of CharPtr[1] =%s",CharPtr[1]);
printf("\n content of CharPtr[2] =%s\n",CharPtr[2]);
printf(" \n content of char a[4]=%s",a);
printf(" \n content of char b[4]=%s",b);
printf(" \n content of char c[4]=%s\n",c);
}
char *keywords[10] is an array of character pointers. So keywords[0], keywords[1].. and so on will have the addresses to different character arrays.
In printf you can use %s and keywords[0] to print the entire character array whose address(i.e. address of the first byte in the array) is stored at keywords[0].
While passing to a function, if you give *keywords, you are referring to the value at(address stored at keywords[0]) which is again an address. So, to get the value instead of address, you can add another *... Hope that clarifies a bit..
I am assuming that you are assigning your first string:
"float"
to the first index position of keyword[0]
char keyword[0] = "float";
which is the first index position of the array:
char keyword[10];
If the previous is the case, then in a sense, you are essentially creating a data structure that holds a data structure. The array of any type is the 'smallest' data structure of that type in C. Considering that in your example you are creating a character array, then you are actually utilizing the smallest data type (char=1bit) at each index position of the smallest built in data structure (the array).
With that said, if in your example, you are attempting to create an array of arrays; your character array
/* Hold ten characters total */
char keyword[10];
was designed to hold 10 characters. One at each index position (which you probably already know). So after declaring the array titled keyword, you then try to initialize the first index position of the array with another (the second) character array:
/* I believe this is what you had stated */
char keywords[0] = "float";
With the second character array having an index of 5 positions in size.
In order to achieve your desired goal, you would essentially be creating an array that basically emulates the effect of a data structure that 'holds' other data structures.
NOTE: If you had/have plans on trying to create a data structure that holds a data structure that holds a data structure. A.K.A. a triple nested data structure and in this case I think that would be a Matrix, WHICH I WOULDN'T RECOMMEND!
None the less, the matrix structure would be in the form of the first index position of keyword, being assigned the whole array of keywords, which would include all of the data stored in each index position of the keywords array. Then there would something probably like: keywords1, keywords2, ... keywords9,
which would essentially emulate the form of:
char *keyword[10] = {
char *keywords0[10] = {"float", etc, etc, etc.};
char *keywords1[10] = {"keyword1", "secondIndexOfThisArray", etc, etc, etc.};
and so
};
So basically from right to left, the keyword array, is an array of pointers that points to array of pointers that points to character arrays.
If that is what you are representing you would be better defining a custom data type of struct/record, and with in that custom structure you would want to define a subordinate or child level of structures. You could also pre-declare them then initialize them.
e.g.
typedef *nestedDataStructures {
struct keyWords[];
struct keyWords1[];
struct keyWords2[];
... and so on.
}; nestedDataStructures
Instead of adding ten structs to one custom structure I would break down into 3 or 4 (how ever many structures and use) and create a module in order to yield symmetrical layers of abstraction as you manipulate your data set.
None the less, you can not create the character array and potentially assign the other character array in the fashion that you did (or who knows maybe you can), but the way you would want to emulate the array that holds arrays, is to create a character pointer array up front, of X number index positions and then initialize then use the character arrays in the form of a strings declared with in the initialization of the original declaration.
So basically you could declare your whole array upfront, then with in your program design, either dereference each index position, use assignment, or print/write the index position.
Like for instance you could always do something like this:
/* Example of the program and declaration with out a function */
#include <stdio.h>
int main(){
/*
* A character pointer array that contains multiple
* character arrays.
*/
char *grewMe[2] = {"I want to ", "grow to be bigger"};
int w = 0;
for(; w < 2;) {
printf("%s", grewMe[w]);
++w;
}
printf(" :-)\n");
w = 0;
return 0;
}
// Output:
// I want to grow to be bigger :-)
Or something like this:
/* Example of program: function passed arguments
* of a pointer to the array of pointers
*/
#include <stdio.h>
void mygrowth(char *growMe[]);
int main(){
char *growMe[2] = {"I want to ", "grow to be bigger"};
mygrowth(growMe);
printf(" :-)\n");
return 0;
}
void mygrowth(char *growMe[])
{
int w = 0;
for (; w < 2;) {
printf("%s", growMe[w]);
++w;
}
}
The assignment of each index position as it's passed as an argument:
/*
* This program compiles, runs and outputs properly
* Example of a program with a function of
* arguments pnt2pnter
*/
#include <stdio.h>
#include <stdlib.h>
void thoughtAsAFunction(char **iThink);
int main()
{
char *iThink[10] = {"I am trying to grow, but it's a hard task to ",
"accomplish. My father is short ",
"my mother is even shorter than him, ",
"what is the probability of me getting taller? ",
"Well both my grandfather's were Six ",
"Foot Five, and both my grandmother's ",
"were over 5 foot 8 inches tall! If my ",
"grandparent's genes point to my parents, and my ",
"parent's genes point to mine I might have a chance ",
"of being 6 foot. Do you know what I mean? "};
thoughtAsAFunction(iThink);
printf(":-)\n");
return 0;
}
void thoughtAsAFunction(char **iThink) {
int andy = 0;
for (; andy < 10;) {
char * pntThroughPnt = iThink[andy];
printf("%s", pntThroughPnt);
++andy;
}
andy = 0;
}
Or pass by reference, with an increment of the loop count variable:
/*
* This program compiles, runs, and outputs all of the character
* arrays.
*
*/
#include <stdio.h>
#include <stdlib.h>
void thoughtAsAFunction(char **iThink);
int main()
{
char *iThink[10] = {"I am trying to grow, but it's a hard task to ",
"accomplish. My father is short ",
"my mother is even shorter than him, ",
"what is the probability of me getting taller? ",
"Well both my grandfather's were Six ",
"Foot Five, and both my grandmother's ",
"were over 5 foot 8 inches tall! If my ",
"grandparent's genes point to my parents, and my ",
"parent's genes point to mine, then I might have a chance ",
"of being 6 foot. Do you know what I mean? "};
int andy = 0;
for (; andy < 10;) {
// pass by reference and increment.
thoughtAsAFunction(&iThink[andy]);
++andy;
}
printf(":-)\n");
andy = 0;
return 0;
}
void thoughtAsAFunction(char **iThink) {
char * pntThroughPnt = *iThink;
printf("%s", pntThroughPnt);
}
Keep in mind that this is the case if you declare the array of pointers (char *array[10];), and each pointer points to an array of characters.
A function I need to use requires a vector argument for return storage with the following signature:
char ***vvar
What am I supposed to pass in there?
How do I access elements afterward?
Let's say you want a function that creates a vector of strings. You might define it and call it like this:
#include "stdio.h"
#include "stdlib.h"
void make_vector(char*** vvar)
{
/* We're going to create a vector of strings. */
char** vector = malloc(sizeof(char*) * 3 );
vector[0] = "Hello";
vector[1] = "world!";
vector[2] = NULL;
/* Now we give the address of our vector to the caller. */
*vvar = vector;
}
int main(void)
{
char** vector_of_strings = NULL;
make_vector(&vector_of_strings);
printf("%s\n", vector_of_strings[0]);
return 0; /* Memory leak is an exercise for the reader. :-) */
}
(In this example it would be simpler to have make_vector return the array, but in a more complex example it's reasonable to pass the address of vector_of_strings.)
I will assume that the vector will contain strings, as that makes the most sense with the signature you describe.
As you also did not give any code, I will assume the function you need to call looks similar to this:
/* This function creates a vector with room for 'length' strings and places it in 'vvar' */
void create_string_vector(int /* in */ length, char*** /* out */ vvar);
As the function expects to be able to change vvar and have that change reflected in the caller, you must pass the address of some variable, so the call should look like
create_string_vector(my_length, &my_var);
That takes care of one level of pointers.
This leaves just the question of how to declare my_var. As it will be a vector, or array, of unknown size, you need to declare it as a pointer. And a string is also a kind of array of unknown size of characters, so you need a pointer for that as well. This leads to the declaration
char* *my_var;
Element access is the easy part: You can treat my_var just as an array:
my_var[0] = "Hello";
This is not a vector by the looks of it.
If the function signature is somethings like function(...,char ***vvar,...), then your solution is not simple.
You need to know how much buffer space you need in each dimension, then create the complicated array as follows:
int dim_1 = 5, dim_2 = 4, dim_3 = 10;
char ***buffer = malloc(sizeof(char**)*dim_1);
for (int i=0;i++;i<dim_1) {
char **buffer_2 = malloc(sizeof(char*)*dim_2);
for (int j=0;j++;j<dim_2) {
char *buffer_3 = malloc(dim_3);
buffer_2[j] = buffer_3;
}
buffer[i] = buffer_2;
}