What is the value we get on printing an array in cpp? - c++

I'm a beginner to c++, I wrote this in my code:
int *ptr;
int arr[4] = {1, 2, 3, 4};
cout << arr << endl;
This outputs to '0x61ff00'.
What does the value mean ?
Thanks!

There is no standard overload for arrays. There is however an overload for const void*. The array decays to a pointer to first element, which further implicitly converts to const void*. The result is an implementation defined textual representation of the address that is the value of the const void* object.
Memory addresses are essentially numbers. 0x is a prefix for hexadecimal numbers.
Following doesn't apply to the example, but does apply to some other arrays: If the array element is char, then the behaviour of the character stream is different, because there is an overload for const char*. In that case, the behaviour is to treat the array as a null terminated string, and the result is the string contained within the array. String literals are null terminated arrays of char.
Example:
std::cout << "Hello, World!";
Output:
Hello, World!
If the array doesn't contain the null terminator, then the behaviour of the program is undefined. Don't ever insert such array into a character stream.

Related

Char array seems to append previous unrelated char arrays to itself? [duplicate]

char sentence[] ={'k','k','k','k','k','k','k','k'}; (8 character)
std::cout << sentence << std::endl;
Then output just "kkkkkkkk".
But if we decrement characters of array (i.e. preceding array have 8 character after less 8 character)
char sentence[] ={'k','k','k','k','k','k','k'}; ( 7 character)
std::cout << sentence << std::endl;
output:
kkkkkkk`\363\277\357\376.
The operand sentence decays to a pointer to first element of the array. The stream insertion operator overload that accepts const char* parameter requires that the pointer is to a null terminated array. If that pre-condition is violated, then the behaviour of the program is undefined.
sentence does not contain the null terminator character. You insert it into a character stream. The behaviour of the program is undefined.
Then output just "kkkkkkkk".
That's one potential behaviour. This behaviour isn't guaranteed because the behaviour of the program is undefined.
But if we decrement length of array then output kkkkkkk`\363\277\357\376.
That's one potential behaviour. This behaviour isn't guaranteed because the behaviour of the program is undefined.
char arrays are often used for null-terminated strings, but not always.
When you write
const char* str = "Hello";
then str is a pointer to the first element of a const char[6]. 5 for the characters, and the rules of the language make sure that there is room for the terminating \0.
On the other hand, sometimes a char array is just that: An array of characters. When you write
char sentence[] ={'H','e','l','l','o'};
Then sentence is an array of only 5 chars. It is not a null-terminated string.
This two worlds (general char array / null-terminated strings) clash when you call
std::cout << sentence << std::endl;
because the operator<< overload does expect a null-terminated string. Because sentence does not point to a null-terminated string, your code has undefined behavior.
If you want sentence to be a string, make it one:
char sentence[] = {'H','e','l','l','o','\0'};
Or treat it like a plain array of characters:
for (const auto& c : sentence) {
std::cout << c;
}
Try using
char sentence[] = {'k','k','k','k','k','k','k','k','\0'};
you must always use a '\0' at the end when you are declaring a char array manually and want to print it. Because either cout or printf function will look for '\0' character and will only stop printing if it finds '\0'. also make sure you wont you it in middle of your array as it wont print the complete array

Output non-null terminated char array behaviours?

char sentence[] ={'k','k','k','k','k','k','k','k'}; (8 character)
std::cout << sentence << std::endl;
Then output just "kkkkkkkk".
But if we decrement characters of array (i.e. preceding array have 8 character after less 8 character)
char sentence[] ={'k','k','k','k','k','k','k'}; ( 7 character)
std::cout << sentence << std::endl;
output:
kkkkkkk`\363\277\357\376.
The operand sentence decays to a pointer to first element of the array. The stream insertion operator overload that accepts const char* parameter requires that the pointer is to a null terminated array. If that pre-condition is violated, then the behaviour of the program is undefined.
sentence does not contain the null terminator character. You insert it into a character stream. The behaviour of the program is undefined.
Then output just "kkkkkkkk".
That's one potential behaviour. This behaviour isn't guaranteed because the behaviour of the program is undefined.
But if we decrement length of array then output kkkkkkk`\363\277\357\376.
That's one potential behaviour. This behaviour isn't guaranteed because the behaviour of the program is undefined.
char arrays are often used for null-terminated strings, but not always.
When you write
const char* str = "Hello";
then str is a pointer to the first element of a const char[6]. 5 for the characters, and the rules of the language make sure that there is room for the terminating \0.
On the other hand, sometimes a char array is just that: An array of characters. When you write
char sentence[] ={'H','e','l','l','o'};
Then sentence is an array of only 5 chars. It is not a null-terminated string.
This two worlds (general char array / null-terminated strings) clash when you call
std::cout << sentence << std::endl;
because the operator<< overload does expect a null-terminated string. Because sentence does not point to a null-terminated string, your code has undefined behavior.
If you want sentence to be a string, make it one:
char sentence[] = {'H','e','l','l','o','\0'};
Or treat it like a plain array of characters:
for (const auto& c : sentence) {
std::cout << c;
}
Try using
char sentence[] = {'k','k','k','k','k','k','k','k','\0'};
you must always use a '\0' at the end when you are declaring a char array manually and want to print it. Because either cout or printf function will look for '\0' character and will only stop printing if it finds '\0'. also make sure you wont you it in middle of your array as it wont print the complete array

C++ Comparison of String Literals

I'm a c++ newbie (just oldschool c). My son asked for help with this and I'm unable to explain it. If he had asked me "how do I compare strings" I would have told him to use strcmp(), but that isn't what is confusing me. Here is what he asked:
int main()
{
cout << ("A"< "Z");
}
will print 1
int main()
{
cout << ("Z"< "A");
}
will also print 1, but
int main()
{
cout << ("Z"< "A");
cout << ("A"< "Z");
}
will then print 10. Individually both cout statements print 1, but executed in a row I get a different answer?
You are comparing memory addresses. Apparently your compiler places the string literals in memory in the order it encounters them, so the first is "lesser" than the second.
Since in the first snippet it sees "A" first and "Z" second, "A" is lesser. Since it sees "Z" first in the second, "Z" is lesser. In the last snippet, it already has literals "A" and "Z" placed when the second command rolls around.
String literals have static storage duration. In all these comparisons there are compared addresses of memory allocated by the compiler for string literals. It seems that the first string literal that is encountered by the compiler is stored in memory with a lower address compared with the next encountered string literal.
Thus in this program
int main()
{
cout << ("Z"< "A");
cout << ("A"< "Z");
}
string literal "Z" was alllocated with a lower address than string literal "A" because it was found first by the compiler.
Take into account that comparison
cout << ("A"< "A");
can give different results depending on the options of the compiler because the compiler may either allocate two extents of memory for the string literals or use only one copy of the string literals that are the same.
From the C++ Standard (2.14.5 String literals)
12 Whether all string literals are distinct (that is, are stored in
nonoverlapping objects) is implementation defined. The effect of
attempting to modify a string literal is undefined.
The same is valid for C.
In the statement:
cout << ("A"< "Z");
You have created 2 string literals: "A" and "Z". These are of type const char * which is a pointer to a null terminated array of characters. The comparison here is comparing the pointers and not the values that they point to. It's this comparing of memory addresses here which is what gives you the compiler warning. The result of the comparison is going to be determined by where the compiler allocated the memory to which is going to be somewhat arbitrary from compiler to compiler. In this case it looks like the first literal found is getting assigned the first memory address by your compiler.
Just like in C to compare these string literals properly you need to use strcmp which will do a value comparison.
However when you do something the more idiomatic c++ way by doing:
cout << (std::string("A") < std::string("Z"));
Then you get the proper comparison of the values as that comparison operator is defined for std::string.
If you want to compare actual C++ strings, you need to declare C++ strings:
int main()
{
const std::string a("A");
const std::string z("Z");
cout << (z < a) << endl; // false
cout << (a < z) << endl; // true
}
In C++, the results are unspecified. I will be using N3337 for C++11.
First, we have to look at what the type of a string literal is.
§2.14.5
9 Ordinary string literals and UTF-8 string literals are also
referred to as narrow string literals. A narrow string literal has
type "array of n const char", where n is the size of the string
as defined below, and has static storage duration (3.7).
Arrays are colloquially said to decay to pointers.
§4.2
1 An lvalue or rvalue of type "array of N T" or "array of unknown
bound of T" can be converted to a prvalue of type "pointer to T".
The result is a pointer to the first element of the array.
Since your string literals both contain one character, they're the same type (char[2], including the null character.)
Therefore the following paragraph applies:
§5.9
2 [...]
Pointers to objects or functions of the same type (after pointer
conversions) can be compared, with a result defined as follows:
[...]
— If two pointers p and q of the same type point to different
objects that are not members of the same object or elements of the
same array or to different functions, or if only one of them is null,
the results of p<q, p>q, p<=q, and p>=q are unspecified.
Unspecified means that the behavior depends on the implementation. We can see that GCC gives a warning about this:
warning: comparison with string literal results in unspecified behaviour [-Waddress]
std::cout << ("Z" < "A");
The behavior may change across compilers or compiler settings but in practice for what happens, see Wintermute's answer.
You are comparing memory addresses. The example that follow explains how to compare 2 strings:
#include "stdafx.h"
#include <iostream>
#include <cstring> //prototype for strcmp()
int _tmain(int argc, _TCHAR* argv[])
{
using namespace std;
cout << strcmp("A", "Z"); // will print -1
cout << strcmp("Z", "A"); // will print 1
return 0;
}
The string constants ("A" and "Z") in C++ are represented by the C concept - array of characters where the last character is '\0'. Such constants have to be compared with strcmp() type of function.
If you would like to use the C++ std::string comparison you have to explicitly state it:
cout << (std::string( "A") < "Z");
A String is representing a pointer to memory area. So you at first compare only memory addresses with such code
"Z"< "A"
comparing strings is done with functions. They depend on "what kind of string" you have. You have char array strings, but they mid also be objects. These objects have other comparision functions. For instance the CString in MFC has the Compare but also the CompareNoCase function.
For your strings you best use the strcmp. If you debug and step in you see what the function does: it compares every char of both strings and return an integer if the first difference occurs or zero if the same.
int result = strcmp("Z", "A");
Here you find some further sample code

C++ char pointer

Why does the following happen?
char str[10]="Pointers";
char *ptr=str;
cout << str << "\n"; // Output : Pointers
int abc[2] = {0,1 };
int *ptr1 = abc;
cout <<ptr1 << "\n"; // But here the output is an address.
// Why are the two outputs different?
As others have said, the reason for the empty space is because you asked it to print out str[3], which contains a space character.
Your second question seems to be asking why there's a difference between printing a char* (it prints the string) and int* (it just prints the address). char* is treated as a special case, it's assumed to represent a C-style string; it prints all the characters starting at that address until a trailing null byte.
Other types of pointers might not be part of an array, and even if they were there's no way to know how long the array is, because there's no standard terminator. Since there's nothing better to do for them, printing them just prints the address value.
1) because str[3] is a space so char * ptr = str+3 points to a space character
2) The << operator is overloaded, the implementation is called depending on argument type:
a pointer to an int (int*) uses the default pointer implementation and outputs the formatted address
a pointer to a char (char*) is specialized, output is formated as a null terminated string from the value it points to. If you want to output the adress, you must cast it to void*
The empty space is actually Space character after "LAB". You print the space character between "LAB" and "No 5".
Your second question: You see address, because ptr1 is actually address (pointer):
int *ptr1;
If you want to see it's first member (0), you should print *ptr1

What is the difference between int and char arrays?

What is the difference between int and char arrays below:
int main()
{
int numbers[] = {2,1,3};
char letter[] = {'a','b','\0'};
cout<< numbers<<endl;
cout<< letter<<endl;
}
Output:
0x22ff12 // an address
ab
Why isn't the 213 displayed ?
I know the name of an array will point to the address of its first element, but why
does a char array display different behavior?
There is no operator<< overload that takes arrays, exactly, so the arguments you pass (eg numbers and letter) undergo array-to-pointer conversion, to void* and char* respectively.
There is an overload of operator<<() that takes a const void*, and another that takes a const char*. When you call:
cout<< numbers<<endl;
the const void* version is matched, but when you call:
cout<< letter<<endl;
the const char* version is matched.
In the const void* version, the pointer is displayed, while with the const char* version, the string is displayed up to the null terminator.
When you print an array with cout it will print the base address of the array.
The exception is with char arrays which have been overloaded to print it as a c-string.
If you want to print the elements of the int array, you need to do it element-by-element.
The reason is thatoperator<< overloaded for const char* which prints each character till it encounters \0.
There is no such overload corresponds to int[N] which prints each element in it. Instead when you write cout << numbers, it invokes operator<< which is overloaded for void*, and which prints the address.
However, if you overload operator<< for T[N], then you can print it like that as well.
Here is a simple illustration:
template<typename T, size_t N>
std::ostream & operator<<(std::ostream & out, const T (&a)[N])
{
for(size_t i = 0 ; i < N ; ++i)
out << a[i] << ' ';
return out;
}
int main()
{
int numbers[] = {2,1,3};
char letter[] = {'a','b','\0'};
cout<< numbers<<endl;
cout<< letter<<endl;
}
Output:
2 1 3
a b
Demo : http://ideone.com/O4T9N
In C, and therefore in C++, a string is often represented by an array of chars terminated in a 0. Therefore an overloaded operator<< is provide for the class std::ostream, of which std::cout is an instance , which prints the char* as a string. There is no such common use of int arrays, nor any convention so the operator would 'know' how many elements to output, so the pointer to the array is matched to the version of operator<< which outputs any other pointer by printing its address.
char arrays are special because there is an overload for operator << that displays the content as a string.
All other arrays will have the address displayed by default.
In C/C++ an array is in fact a pointer to the first element. A pointer holds the address where a value is stored. Therefore, if you print the pointer numbers, you will get the address where the first value (2) is stored in memory.
char* is an exception, as it will behave as a string when you try to print it.
Your code mostly refers C. An array of char is de-facto representation of strings in C. On the other hand, an array in C is also a pointer to the memory cell (an address of the cell) that holds the first element of the array.
So, when you print out an array of characters, you in fact print out a string (because C treats it that way). When you're printing an array of integers, you're printing out the address of the first element of the array.
numbers is a pointer. All arrays in C++ are in fact pointers, numbers[3] just means "the value at the memory address &number+3", so you're outputting the memory address of the first element in numbers.
There is no reason the compiler should know where your int[] array ends, but tradition and standard libraries dictate that C strings are null terminated char[] arrays. There is no such tradition or library support for null terminated int[] arrays.
There are C++ pretty printers templates available if you need this functionality. I vaguely recall that one employs an array's bound when the type actually knows the bound, i.e. your code still won't work since you use [] not [3].
Just fyi, your code cannot be fixed by replacing the [] with a [3] inside the STL, although perhaps operator<< could be overloaded.
A char array contains characters.
It can be initialized like:
char arr[4]={'a','b','c','\0'};
char arr[4]={"abc"};
An integer array contains integers.
It can be initialized like:
int arr[4]={1,2,3,4};