The snippet
char *encrypt(char *string, size_t length) {
}
defines a function named encrypt
, which takes a char *
and a size_t
as arguments, and returns a char *
. As written, the function body is empty and will trigger at least one diagnostic because it isn’t returning a value.
It looks like it’s meant to take an unencrypted string as the string
argument, and return the encrypted version of it:
char unenc[] = "This is a test";
char *enc = encrypt( unenc, strlen( unenc ) );
We’re dealing with pointers because of how C treats array expressions. A string is a sequence of character values including a 0-valued terminator – the string “hello” is represented as the sequence {'h', 'e', 'l', 'l', 'o', 0}
. Strings are stored in arrays of character type (char
for ASCII, EBCDIC, and UTF-8 encodings, wchar_t
for “wide” encodings like UTF-16).
However, unless it is the operand of the sizeof
or unary &
operators, or is a string literal used to initialize a character array in a declaration, an expression of array type is converted (“decays”) to an expression of pointer type, and the value of the expression is the address of the first element of the array.
We defined unenc
as an array of char
large enough to hold the string "This is a test"
(14 characters plus the 0 terminator). When we pass unenc
as an argument to encrypt
, it “decays” from type char [15]
to char *
, and what the function actually receives is the address of the first element of the array (&unenc[0]
).
Array expressions cannot be the target of an assignment, and functions cannot return array types. However encrypt
is meant to work internally, it cannot return the encrypted string as an array; it can only return a pointer to the first element of the array storing the string.
Now, without knowing the implementation, it’s possible that encrypt
is encrypting the string in place, overwriting the original contents of the array, and return that same address:
char *encrypt( char *string, size_t length )
{
for ( size_t i = 0; i < length; i++ )
string[i] = replace_char( string[i] );
return string;
}
Since string
is declared char *
and not const char *
, that’s a reasonable inference to make. And it would avoid memory management headaches. Of course you’re destroying your input, so there are tradeoffs there.
If it’s not encrypting in place, then the encrypt
function needs to either allocate new memory, or use memory that’s available outside the lifetime of the function (either a global or a local that’s been declared static
, which brings its own headaches):
char *encrypt( char *string, size_t length )
{
char *e = malloc( length + 1 );
if ( e )
{
for ( size_t i = 0; i < length; i++ )
e[i] = replace_char( string[i] );
}
return e;
}
solved I’m just beginning to learn C: Can someone explain what the pointers and typecasting are doing in this code? [closed]