Reputation: 702
Suppose I have something like this
int strLen;
printf("Please enter a number: ");
scanf("%d", &strLen);
char *myString;
myString = (char*) malloc(strLen*sizeof(char));
then you fill string with something like "Hello World!" but now I want to just print out "World!" Since my string is just a pointer reference, I can't call it out by indexes ie.
for(int i=6;i<strLen;i++)
{
printf("%s", myString[i]);
}
// THIS IS AN INCORRECT WAY TO DO THIS
How could I refer to a specific character or even pass the array onto another function of the program if all I have is the array base pointer? Can I ever get the full functionality as if I declared it as a static array before compile time?
Upvotes: 0
Views: 16651
Reputation: 123448
How could I refer to a specific character or even pass the array onto another function of the program if all I have is the array base pointer?
Several things to remember:
Except when it is the operand of the sizeof
or unary &
operators, or is a string literal being used to initialize another array in a declaration, an expression of type "N-element array of T
" will be replaced with ("decay to") an expression of type "pointer to T
" whose value is the address of the first element of the array;
In the context of a function parameter declaration, T a[N]
and T a[]
are identical to T *a
(IOW, a
will be declared as a pointer to T
, not an array of T
- note that this is only true for function parameter declarations);
The subscript operation a[i]
is defined as *(a + i)
- start with a base address specified by the pointer expression a
, offset by i
elements (not bytes), and dereference the result;
In C, you do not need to cast the result of malloc
(or calloc
or realloc
), since it returns a value of type void *
, which may be assigned to any other object pointer type. Adding the cast may suppress a useful diagnostic if you forget to include stdlib.h
or otherwise don't have a prototype in scope. Note that this is not true for C++ - a cast is required there, but if you're writing C++ you should be using new
instead of malloc
anyway.
This is a long-winded way of saying that, in many contexts, array expressions and pointer expressions can be treated the same way. Taking printf
as an example:
int main(void)
{
char foo[] = "This is a test";
char *bar = foo;
printf("%s\n", foo);
printf("%s\n", &foo[0]);
printf("%s\n", bar);
return 0;
}
printf
expects the argument corresponding to %s
to have type char *
, or "pointer to char
", not "array of char
". The three printf
calls above are all equivalent. In the first call, foo
is an array expression with type "15-element array of char
". By the first rule mentioned above, it will be replaced with an expression of type "pointer to char
" whose value is the address of the first element. The second and third calls pass the pointer value directly, just using different expressions to accomplish the same effect.
As far as printf
is concerned, all three expressions yield the same result -- the address of the first element of a sequence of char
values, terminated by 0
.
What does this mean for your code? Well, for one thing, you can use the subscript operator on mystring
as though it were an array type:
printf("%s\n", &mystring[6]); // prints "World!"
Note that the subscript operator []
has higher precedence than the unary &
operator, so the above is interpreted as &(mystring[6])
- we subscript into mystring
and then take the address of the result.
You can pass mystring
to any function that you would pass an array of char
to:
void foo(char str[]) // identical to char *str
{
// do something with str
}
...
int main(void)
{
char str[] = "Hello, World!";
char *mystr = malloc(strlen(str) + 1); // note no cast
strcpy(mystr, str);
foo(str);
foo(mystr);
...
}
Again, as far as the function foo
is concerned, its argument is type char *
, not array of char
. The expression str
decays to a pointer value, and mystr
is a pointer value to begin with.
Upvotes: 4
Reputation: 121649
A couple of things:
1) Allow for the null terminator in your "malloc()":
int strLen;
...
char *myString = (char*) malloc(strLen+1);
2) The "sizeof(char)" is kind of duplicate redundant. No harm - but no purpose, either. So I omitted it.
3) This is wrong:
for(int i=6;i<strLen;i++)
{
printf("%s", myString[i]);
}
4) This is better:
for(int i=6;i<strLen;i++)
{
printf("%c", myString[i]);
}
Upvotes: 1
Reputation: 18697
You can take the address of the character at a certain array index.
So, try this if you just want to print out 'world!':
#include <stdio.h>
int main(int a, char** b)
{
int strLen;
char *myString;
myString = "hello world!";
printf("%s", &myString[6]);
return 0;
}
Upvotes: 0