pointers *char and &char - c++

I have doubt on below programme
#include "stdafx.h"
#include "stdio.h"
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
char *chr = "hello";
cout<<chr; //hello
cout<<endl;
cout<<*chr; //h
cout<<endl;
cout<<*(&chr); //hello
system("pause");
return 0;
}
why second cout prints h where as third one prints hello when represents the same

To be a little bit more explicit. chr is a pointer pointing to a chunk of memory where the characters 'h','e','l','l' and 'o' are stored. After the last character of chr is a terminating \0. This is needed to signal that the chunk pointed by chr is now over.
When passing chr to cout, cout will read (not cout it self but the underlying function wich is called by using the << operator) this chunk up to the terminating \0. When passing *chr to cout you dereference the pointer and simply pass the first character pointed by chr to cout ('h').
*(&chr) is the same thing as just chr because the adress-of operator gives you the adress of chr wich is a pointer to a pointer to character. Dereferencing it using * will then give you the pointer pointing to the chunk of memory starting with 'h' and coutwill again read up to the terminating \0.
EDIT
As birdypme pointed out correctly, the * operator (dereferencing operator) is the inverse to the address-of operator. It is like + and -. Therefore something like this
cout << *(&(*(&chr))) << endl;
will still be the same as
cout << chr << endl;
You can do this to infinity if you like to.
cout << *(&(*(&(*(&(*(&(*(&(*(&(*(&chr))))))))))))) << endl; // I hope i didn't miss a ')'

Because in the second case, you are passing to cout a single char, the one pointed by chr, that is the first of the C-string "hello".

In the second example you are dereferencing the pointer. This is the same as using chr[0] and in this case it is h.
In the last example you are taking the address of chr and then dereferencing:
&chr --> char**
*(&chr) --> char*
So at the and you again have a char*

Your statement
cout<<*chr; is same as cout<<chr[0];
because the pointer is dereferenced and passes only the first character pointed by chr
In case of cout<<*(&chr); , if i convert it into words, it would be, print the value present at the address of chr. Now since chris a pointer, you will get a pointer to a pointer by this statement &chrand the again you are dereferencing it, which gives you hello.

Related

Are std::string with null-character possible?

I initialized a C++ string with a string literal and replaced a char with NULL.
When printed with cout << the full string is printed and the NULL char prints as blank.
When printed as c_str the string print stop at the NULL char as expected.
I'm a little confused. Does the action came from cout? or string?
int main(){
std::string a("ab0cd");
a[2] = '\0'; // '\0' is null char
std::cout << a << std::endl; // abcd
std::cout << a.c_str() << std::endl; // ab
}
Test it online.
I'm not sure whether the environment is related, anyway, I work with VSCode in Windows 10
First you can narrow down your program to the following:
#include <iostream>
#include <string>
int main(){
std::string a("ab0cd");
a[2] = '\0'; // replace '0' with '\0' (same result as NULL, just cleaner)
std::cout << a << "->" << a.c_str();
}
This prints
abcd->ab
That's because the length of a std::string is known. So it will print all of it's characters and not stop when encountering the null-character. The null-character '\0' (which is equivalent to the value of NULL [both have a value of 0, with different types]), is not printable, so you see only 4 characters. (But this depends on the terminal you use, some might print a placeholder instead)
A const char* represents (usually) a null-terminated string. So when printing a const char* it's length is not known and characters are printed until a null-character is encountered.
Contrary to what you seem to think, C++ string are not null terminated.
The difference in behavior came from the << operator overloads.
This code:
cout << a.c_str(); // a.c_str() is char*
As explained here, use the << overloads that came with cout, it print a char array C style and stop at the first null char. (the char array should be null terminated).
This code:
cout << a; // a is string
As explained here, use the << overloads that came with string, it print a string object that internally known is length and accept null char.
string end limit (boundary) is not 0 (NULL) like simple char* but its size keep internally in its member data as it's actually user-defined type (an instantiated object) as opposed to primitive type, so
int main(){
string a("abc0d");
a[3] = 0; // '\0' is null char
a.resize(2);
std::cout << a << std::endl; // ab
std::cout << a.c_str() << std::endl; // ab
}
i'm sorry change your code to be more comfortable, watch as it results in
ab
ab
good learning: http://www.cplusplus.com/reference/string/string/find/index.html

Why strstr() - char pointer = number?

I have this program:
#include <iostream>
#include <conio.h>
#include <string.h>
using namespace std;
int main()
{
char char1[30] = "ExtraCharacter", char2[30] = "Character", *p;
p = strstr(char1, char2);
cout << "p: " << p << endl;
cout << "char1: " << char1 << endl;
cout << "(p-char1): " << (p-char1) << endl;
return 0;
}
When I run it, I get:
p: Character
char1: ExtraCharacter
(p-char1): 5
as expected.
But this is not the problem, I'm not sure why "Character" - "ExtraCharacter" is an integer (5)? Perhaps not an integer, but a number/digit anyways.
Actually I don't understand why is "Character" stored in p, and not the memory address.
If I understood well from a book, strstr() returns a memory address, shouldn't it be more like a strange value, like a hex (0x0045fe00) or something like that? I mean, it's cout << p not cout << *p to display the actual value of that memory address.
Can someone explain me how it works?
P.S.: I apologize if the title is not that coherent.
But this is not the problem, I'm not sure why "Character" - "ExtraCharacter" is an integer (5)?
You subtract one pointer from another and result - number, distance from char char1 points to to char p points to. This is how pointer arithmetic works.
Note: this subtraction is only valid when both pointers point to the same array (or behind the last element), which is the case in your code, but you need to be careful. For example if strstr() does not find susbtring then it would return nullptr and your subtraction will have UB. So at least check p before subtracting (and passing nullptr to std::cout would have UB as well)
If I understood well from a book, strstr() returns a memory address, shouldn't it be more like a strange value, like a hex (0x0045fe00) or something like that? I mean, it's cout << p not cout << *p to display the actual value of that memory address.
Yes p is a pointer aka memory adress. std::ostream has special rule how to print pointers to char - as strings, because strings in C stored that way. If you want to see it as a pointer just cast it:
std::cout << static_cast<void *>( p );
then you will see it as an address.
To display address, you have to cast char* to void*:
std::cout << "p: " << static_cast<const void*>(p) << std::endl;
Demo
For std::basic_ostream (type of cout), character and character string arguments (e.g., of type char or const char*) are handled by the non-member overloads of operator<< which are being treated as strings. char[30] will be decayed to const char* argument and basic_ostream will output the null terminated string at the address of the pointer.
As for (p-char1), the result of subtracting two pointers is a std::ptrdiff_t. It is an implementation-defined signed integer. That's why the output is 5

Pointer and char array confusion

#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;
}

C++ pointer and array basics

Code:
#include <iostream>
using namespace std;
int main(int argc, const char * argv[]) {
char testChar[] = {'a','b','c'};
char *testPointer = testChar ;
cout << testPointer << endl;
return 0;
}
Question:
When I use cout << mypointer,
Why does to print each letter of the array and the mess(refer to
output) at the end? My assumption is when I see out the pointer
points to the first letter prints then the second then etc and
prints the stuff at the end.
What is the mess (refer to output) at the end , the address?
Comments:
I know at the end of the array there's suppose to be a null pointer right?
I learnt this a year ago and forget please help me recall what is going on.
Output:
abc 310 367 277_ 377
Program ended with exit code: 0
When printing out a string (or char array in your case), it must be terminated by a null character \0, otherwise cout will continue to print out characters located in memory past the intended string until it either hits a null character, or it accesses memory it is not allowed to read from which results in a segmentation fault.
That "mess" at the end that is being printed are the values located in the memory locations immediately past the char array.
Also after initializing char testChar[] = "abc"; you actually don't need 'char *testPointer = testChar' statement since testChar is itself an address to the first element of the array. So cout << testChar << endl;will do.

What's wrong with my memcpy?

I have written a function to implement memcpy
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
char *memcpy(char *dest,char *src,int n){
char *ch=dest;
while (n--)
*ch++=*src++;
return dest;
}
int main(){
char *src="georgia";
int n=strlen(src);
char *dest=new char[n];
std::cout<<*memcpy(dest,src,n)<<std::endl;
return 0;
}
But it only prints a single g. Why?
Because you're printing a single character.
std::cout<<*memcpy(dest,src,n)<<std::endl;
This dereferences the destination buffer (*memcpy) and therefore returns the first character of the string (which is g). You should be fine using this:
std::cout << memcpy(dest, src, n) << std::endl;
Other than that, it's still not gonna work: you need to include the terminating NULL character of your string in the copy, but strlen excludes it from the length of the string; so your buffer is missing 1 character. You need to add 1 to n to balance it, and everything should be fine.
int n = strlen(src) + 1;
Nothing wrong with the memcpy function but you have the * operation on the result. If we break the print line down it is...
char * result = memcpy(dest,src,n);
std::cout << *result << std::endl;
You really want...
std::cout << memcpy(dest,src,n) << std::endl;
Your memcpy() returns a pointer to char. In the line
std::cout<<*memcpy(dest,src,n)<<std::endl;
you dereference the pointer (you use operator*) so effectively you send one char (the one the return value points to) to the stream.
There is a bug in your code. strlen returns number of characters in the literal "georgia", but wihtout the terminating null character. You should increase n by one, to allocate appropriate storage for dest and to copy also the terminating null character.
You're dereferencing a char*, which is a char. This will be the first character, g.