I do not understand the following:
int main() {
char ch[13] = "hello world";
function(ch);
return 0;
}
void function( char *ch) {
cout << ch;
}
This outputs "hello world". But if I derefference the pointer ch the program outputs the first letter i.e. "h". I cannout figure out why.
cout << *ch;
As someone stated in the comments section the result of derefferencing the pointer to an array is a plain char.
Let me explain why:
Your ch pointer indicates the adress of the start of the char array, so when you call cout<<ch it will show on the screen all you have in the memory starting from the ch adress and goes secquentially till a first NULL value appears and stops.
And when you call cout<<*ch it will take the value that you have stored on the start adress of the array which is h.
Derefferencing means that you take the value from a specific adress.
Hope it helped! :)
When you pass an array into a function, either directly or with an explicit pointer to that array, it has decayed functionality, in that you lose the ability to call sizeof() on that item, because it essentially becomes a pointer.
So it's perfectly reasonable to dereference it and call the appropriate overload of the stream << operator.
More info: https://stackoverflow.com/a/1461449/1938163
Also take a look at the following example:
#include <iostream>
using namespace std;
int fun(char *arr) {
return sizeof(arr);
}
int fun2(char arr[3]) {
return sizeof(arr); // It's treating the array name as a pointer to the first element here too
}
int fun3(char (&arr)[6]) {
return sizeof(arr);
}
int main() {
char arr[] = {'a','b','c', 'd', 'e', 'f'};
cout << fun(arr); // Returns 4, it's giving you the size of the pointer
cout << endl << fun2(arr); // Returns 4, see comment
cout << endl << fun3(arr); // Returns 6, that's right!
return 0;
}
or try it out live: http://ideone.com/U3qRTo
Related
#include <iostream>
using namespace std;
char* input(char **S);
int main()
{
char **S = new char *;
char *K = input(S);
//cout << K << endl;
cout << *K << endl;
}
char* input(char **S)
{
cout << "Enter string: ";
cin >> *S;
cout << S << endl; // Prints address of S
cout << *S << endl; //Prints content of address stored in S
return *S;
}
I am failing to understand why when I print out *K, I just get the first character of the input string but if I print out the commented line(just K alone) I get the whole string. Any help with explaining what I am not able to see or understand is appreciated.
Let's understand how arrays work:
// Let's say I have one character array
char arr[] = {'a', 'b', 'c', 'd'};
In here, the name of the array i.e. arr acts as the pointer to the first element of the array. However, do note that it is NOT the pointer to the first element to avoid confusion, it just have an implicit conversion to pointer of element type. More details can be found here: https://stackoverflow.com/a/1641963/10821123
Now since array is contiguous, the rest of the elements can be determined.
// so ideally, the below two statements would print the same thing
cout << &arr << endl;
cout << (void*) &arr[0] << endl;
// the above line just takes out the address of the first pointer
Now coming to your question, I'll convert my example to a string one:
char *K = "abc";
cout << *K << endl; // a
cout << K << endl; // abc
Note that the above assignment of char *K = "abc"; will give you a warning: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings]
The pointer only holds the address of the first element of the array, so when you dereference the pointer, it prints the first element, i.e. *K is interpreted as K[0]
Now there's an overload of operator <<, so what it does is if it sees a character pointer i.e. char*, it prints the complete null-terminated string, that's why in your case too, it is printing the whole string.
The goal is to write a function that outputs the address of the first element of a string that is equal to a character, however I am confused by the result.
When evaluating the function with a string that contains said character in the first place, I get a difference of 2 bytes between the address of the beginning of the string and the address of the first element. E.g. 0x7ffe559716d0 and 0x7ffe559716e0.
Shouldn't the address be the same?
#include <iostream>
#include <string>
using namespace std;
const char* first_char(const char* str, const char ch)
{
for (int i = 0; str[i] != 0; ++i)
{
if (str[i] == ch)
return (i+str);
}
return 0;
}
int main() {
string str1 = "jasdfgjhk";
const char ch1 = 'j';
cout << &str1 << endl;
//should be the same address as above?
cout << (void*)first_char(&str1[0], ch1) << endl;
return 0;
}
Change this:
cout << &str1 << endl;
to this:
cout << (void*)str1.data() << endl;
and you will get the same address as the one returned by your function.
The reason is that std::string is not just an array of characters, it's a class, who has a data member that is an array and stores the characters of the string.
By using data(), you are getting that array. When you print its address it gives you the actual address of the array, and of the class as before
Please note that
&str
is the starting address of 'string' object. The string object is not the string itself. It contains a (hidden) dynamic pointer that points to the string itself. So by the above you get "something" like a pointer to a pointer to the string.
But with:
&str1[0]
you really get a pointer to the first character in the string.
I have troubles understanding strings as pointers. Apparently a string is understood as a pointer which points to the first address of the string. So using the "&"-operator I should receive the address of the first character of the string. Here's a small example:
#include "stdafx.h"
#include <iostream>
using namespace std;
int main(){
char text[101];
int length;
cout << "Enter a word: ";
cin >> text;
length = strlen(text);
for (int i = 0; i <= length; i++) {
cout << " " << &text[i];
}
return 0;
}
When entering a word such as "Hello", the output is: "Hello ello llo lo o". Instead I expected to receive the address of each character of "Hello". When I use the cast long(&text[i]) it works out fine. But I don't understand why. Without the cast, apparently the "&"-operator gives the starting address of the string to be printed. Using a cast it gives the address of every character separately.
Maybe sb. can explain this to me - I'd be really grateful!
&text[i] is equivalent to text + i and that shifts the pointer along the char[] array by i places using pointer arithmetic. The effect is to start the cout on the (i)th character, with the overload of << to a const char* called. That outputs all characters from the starting point up to the NUL-terminator.
text[i] however is a char type, and the overload of << to a char is called. That outputs a single character.
In C++, if you want a string, then use std::string instead. You can still write cin >> text; if text is a std::string type! Your code is also then not vulnerable to overrunning your char buffer.
If you have a character array storing a string as for example
char text[] = "Hello";
then the array is initialized like
char text[] = { 'H', 'e', 'l', 'l', 'o', '\0' };
In this statement
std::cout << text;
there is used operator << overloaded for the type const char * and the array text is converted implicitly to pointer to its first element.
You could write instead
std::cout << &text[0];
because in the both statements the expressions text and &text[0] have type char *.
The operator overloaded for the type const char * outputs characters starting from the address at the pointer until a zero character is encountered.
So if instead of the statement
std::cout << &text[0];
you'll write
std::cout << &text[1];
then the only thing that is changed is the starting address of the string and nothing more. That is in fact you are outputting string that is represented like
{ 'e', 'l', 'l', 'o', '\0' }
If to write
std::cout << &text[2];
that is if the pointer in the right side of the expression is moved one position right then it means that you'll deal with the string
{ 'l', 'l', 'o', '\0' }
and so on.
That is the operator << overloaded like
template<class traits>
basic_ostream<char, traits>& operator<<(basic_ostream<char, traits>&,
const char*);
just outputs entities pointed to by the second parameter as strings.
If you want to output the value of the pointer itself instead of the string pointed to by the pointer you should use another overloaded operator << declared like
basic_ostream<charT, traits>& operator<<(const void* p);
Tp invoke it you should write for example
std::cout << ( void * )text;
or
std::cout << ( void * )&text[i];
where i is some index.
Instead of the C casting you can use C++ casting like
std::cout << static_cast<void *>( &text[i] );
To print the address of an array element, you could do:
cout << " " << (void*)&text[i];
This:
cout << " " << &text[i];
is equivalent to this:
cout << " " << text + i;
which means that you ask to print the string, starting from index i.
#include <iostream>
using namespace std;
int main()
{
char str[] {"TESTING"};
char *p {str};
cout << (p++, *++p);
cout << *p++;
cout << p;
return 0;
}
It returns "SSTING"
I know maybe this post isn't exactly for stackoverflow but I can't figure out what it does, and couldn't find any documentation about it
cout << (p++, *++p);
First time I saw round brackets with comma in cout... what's their function?
and shouldn't this line alone say "TESTING" but it seems to say only TING
cout << p;
Thank you!
Let's go line by line:
char str[] {"TESTING"};
This line defines a variable named str of type array of 8 chars, and initializes it with the characters TESTING plus a NUL char to mark the end.
char *p {str};
This one defines a variable named p of type pointer to char and initializes it to the address of the first char of the array str (the first T). This happens because the array automatically decays into a pointer in most uses.
cout << (p++, *++p);
This line does several things. The , operator first evaluates the left-hand operator p++, that increments the pointer, now points to the E; then it evaluates the right-hand operator *++p, but that is a pre-increment operator so it increments the pointer again (it points to S). Finally the * operator accesses to the memory pointed to by p, the result is a S. And that character is printed into STDOUT.
cout << *p++;
This one is easy. The * operator accesses the char pointed to by p (the S again) and prints it in STDOUT. Then it increments the pointer, because it is a post-increment operator. Now it points to the second T.
cout << p;
And at least, this line prints the string pointed to by p until it finds a NUL character. Since p is pointing to the second T of your array it will print TING.
Putting all those outputs together you get SSTING.
Not exactly an answer, but a breakdown of what was the code doing,
#include <iostream>
using namespace std;
int main()
{
char str[]{"TESTING"};
char *p{str}; // p points to: 'T'
p++; // p points to: 'E'
++p; // p points to: 'S'
cout << *p; // output a single char: 'S'
cout << *p; // ouptut a single char: 'S'
p++; // p points to: 'T'
cout << p; // output a (char *) type pointer, AKA a C-string, "TING";
return 0;
}
how can i print a char array such i initialize and then concatenate to another char array? Please see code below
int main () {
char dest[1020];
char source[7]="baby";
cout <<"source: " <<source <<endl;
cout <<"return value: "<<strcat(dest, source) <<endl;
cout << "pointer pass: "<<dest <<endl;
return 0;
}
this is the output
source: baby
return value: v����baby
pointer pass: v����baby
basically i would like to see the output print
source: baby
return value: baby
pointer pass: baby
You haven't initialized dest
char dest[1020] = ""; //should fix it
You were just lucky that it so happened that the 6th (random) value in dest was 0. If it was the 1000th character, your return value would be much longer. If it were greater than 1024 then you'd get undefined behavior.
Strings as char arrays must be delimited with 0. Otherwise there's no telling where they end. You could alternatively say that the string ends at its zeroth character by explicitly setting it to 0;
char dest[1020];
dest[0] = 0;
Or you could initialize your whole array with 0's
char dest[1024] = {};
And since your question is tagged C++ I cannot but note that in C++ we use std::strings which save you from a lot of headache. Operator + can be used to concatenate two std::strings
Don't use char[]. If you write:
std::string dest;
std::string source( "baby" )
// ...
dest += source;
, you'll have no problems. (In fact, your problem is due to the fact
that strcat requires a '\0' terminated string as its first argument,
and you're giving it random data. Which is undefined behavior.)
your dest array isn't initialized. so strcat tries to append source to the end of dest wich is determined by a trailing '\0' character, but it's undefined where an uninitialized array might end... (if it does at all...)
so you end up printing more or less random characters until accidentially a '\0' character occurs...
Try this
#include <iostream>
using namespace std;
int main()
{
char dest[1020];
memset (dest, 0, sizeof(dest));
char source[7] = "baby";
cout << "Source: " << source << endl;
cout << "return value: " << strcat_s(dest, source) << endl;
cout << "pointer pass: " << dest << endl;
getchar();
return 0;
}
Did using VS 2010 Express.
clear memory using memset as soon as you declare dest, it's more secure. Also if you are using VC++, use strcat_s() instead of strcat().