Logical AND operator on negative number in C - c++

there!! Why's the output different in both codes whereas logic is same!!
Code 1:
#include <iostream>
using namespace std;
int main() {
int a, b, c, d;
a = b = 1;
c = a || --b;
d = a-- && --b;
cout << a << "\t" << b << "\t" << c << "\t" << d << "\n";
}
Output:
~ ❯ g++ main.cpp && ./a.out
0 0 1 0
Code 2:
#include <iostream>
using namespace std;
int main() { cout << -1 && 1; }
Output:
~ ❯ g++ main.cpp && ./a.out
-1~ ❯
Code 3:
#include <iostream>
using namespace std;
int main() { cout << 1 && -1; }
Output:
~ ❯ g++ main.cpp && ./a.out
1~ ❯
I guess it's doing bitwise operation. But I'm not sure, please help.
Moreover, I tried same in C.
#include <stdio.h>
int main() {
printf("%d\n", -1 && 1);
printf("%d\n", 1 && -1);
}
Output:
~ ❯ cc -Wall main.c && ./a.out
1
1
It's very confusing. I think it's implementation-dependent as both C and C++ compiler behaved differently. Please spread some light on it.

As people already disclosed, the issue is that cout << 1 is what is first executed during runtime, then && -1, because that's how the operation order works.
However, if you change your command to cout << (1 && -1);, the order changes, so that the parenthesis is first executed, then the output of the operation is passed onto cout.
Lastly, although not importart to the question, putting an endl to the end of your couts is common practice, something like this: cout << (1 && -1) << endl;

Related

Check that command line input is one argument and it must be a numeric greater than 3 only in c++

Program in c++.
My goal for this assignment is to make sure the user enter only one argument in command line and that argument has to contain digits only and greater than 3. Otherwise, print error.
For example:
$ ./a.out 4
Successful!
$ ./a.out abc
Must be a numeric string grater than 3
$ ./a.out 4 abc
Must be one argument only
$ ./a.out 2
Must be a numeric string greater than 3
$ ./a.out 2ab
Must be a numeric string
This is my code so far to handle accepting one argument and greater than 3. I don't know to handle the numeric string part.
int main(int argc, char **argv){
if (argc == 2){
int num = atoi(argv[1];
if (num >3){
cout << "Successful" << endl;
else{
cout <<"Must be a numeric string greater than 3"<< endl;
}
else{
cout << "Must be one argument" << endl;
}
return 0;
}
I have tried this and got segmentation error.
int main(int argv, char **argv){
if (argc == 2){
int num = atoi(argv[1];
int i;
if (num >=3 && isdigit(argv[1][i]){
cout << "Successful" << endl;
else{
cout << "Must be a numeric string greater than 3"<<endl;
}
else{
cout << "Must be one argument" << endl;
}
return 0;
}
You could use std::strtol instead of atoi; this way you can check that the parsing stopped at the end of that string.
here is code that compiles and does not crash but doesn't produce the right answer. It doesn't work because you are only looking at the first char of argv[1]. Why did it crash, becuase you indexed using i which was untitialized
#include <iostream>
#include<ctype.h>
int main(int argc, char** argv) {
if (argc == 2) {
int num = atoi(argv[1]);
int i = 0;// <<<<========================================
if (num >= 3 && isdigit(argv[1][i])) {
std::cout << "Successful" << std::endl;
}
else {
std::cout << "Invalid" << std::endl;
}
}
else {
std::cout << "Must be one argument" << std::endl;
}
return 0;
}
to make it do the right thing you need to loop over all argv and inside that loop you must loop over all chars in argv[i]
note that I removed the using namespace - see here Why is "using namespace std;" considered bad practice?
Your text and your code are at odds with each other. Is 3 acceptable or not? My code below assumes it is not based on what you wrote.
The big thing here is that atoi() lacks the ability to tell you if the whole string was processed or not. You want to use what C++ provides from <string>, std::stoi() or the long or long long variations depending on what you expect a reasonable range of inputs to be.
std::stoi() has a second output parameter that tells you how many characters were processed. What you then need to check is if the number of characters processed is the length of the string. If not, some non-numeric charcters were entered.
Example code below.
#include <cstring>
#include <iostream>
#include <string>
int main(int argc, char* argv[]) {
if (argc != 2) {
std::cerr << "USAGE: ./a.out ARG\n";
return 1;
}
std::size_t loc;
int val;
// The try block is necessary because std::stoi() throws if the resulting
// number cannot be contained in the type, and if processing fails on the
// first character.
try {
val = std::stoi(argv[1], &loc);
} catch (...) {
std::cerr << "INVALID PARAMETER\n";
return 2;
}
if (loc != std::strlen(argv[1])) {
std::cerr << "INPUT MUST BE FULLY NUMERIC\n";
return 3;
}
if (val <= 3) {
std::cerr << "Parameter must be > 3\n";
return 4;
}
std::cout << "Parameter: " << val << '\n';
}
Test runs:
~/tmp
❯ ./a.out
USAGE: ./a.out ARG
~/tmp
❯ ./a.out 1
Parameter must be > 3
~/tmp
❯ ./a.out 4
Parameter: 4
~/tmp
❯ ./a.out 2ab
INPUT MUST BE FULLY NUMERIC
~/tmp
❯ ./a.out ab
INVALID PARAMETER
Other answers are good and correct. My goto for stuff like this is to use a stringstream.
#include <optional>
#include <sstream>
#include <string>
template <typename T>
auto string_to( const std::string & s )
{
T value;
return (std::istringstream( s ) >> value >> std::ws).eof()
? value
: std::optional <T> {};
}
It is easy enough to use:
#include <iostream>
int error( const char * message )
{
std::cerr << message << "\n";
return 1;
}
int main( int argc, char ** argv )
{
if (argc != 2) return error( "Must be one argument only" );
auto n = string_to<int>( argv[1] );
if (!n) return error( "Must be a numeric string" );
if (n <= 3) then error( "Must be a numeric string grater than 3" );
std::cout << "Successful!\n";
}
The basic principle behind all these answers is you must try to convert it to an integer to see if it is, in fact, an integer.
I like my little utility function (string_to<type>()) because it does all the dirty work correctly: it attempts to convert the value, meaning there may be whitespace before the value but nothing else. It then reads any remaining whitespace and checks for EOF (meaning nothing but whitespace may follow the value). Only if all the checks pass do you get a value back.
I like std::optional because it is exactly for these kinds of things — either you have a value or you do not. You could throw instead, or return a default value, or whatever works. Heck, you could inline it in your main function:
int main(...)
{
...
int value;
if (!(std::istringstream( argv[1] ) >> value >> std::ws).eof())
error( ... );
That’s ugly though, and not very descriptive. I prefer to put things in little helper functions (which the compiler may very well inline) with nice, descriptive names. Like that error function I used there: it tells you exactly what is going on just by reading the code.

Is there anything redundant that I have done or am I, a C++ newbie, missing out anything here?

CODE:
#include <iostream>
#include <cmath>
using namespace std;
//To import packages we use #include.
int integers() {
//Math operations passed onto cout will automatically calculate itself.
inum ++;
dnum --;
cout << inum << endl;
//For example, pow()
cout << pow(2, 6);
//++ function makes variables increment by 1, -- also does that, reversed.
}
ERROR:
[Running] cd "c:\Users\Administrator\Desktop\C++Workplace\C++Basics\" && g++ NumberUses.cpp -o
NumberUses && "c:\Users\Administrator\Desktop\C++Workplace\C++Basics\"NumberUses
C:/TDM-GCC-32/bin/../lib/gcc/mingw32/9.2.0/../../../../mingw32/bin/ld.exe: C:/TDM-GCC-
32/bin/../lib/gcc/mingw32/9.2.0/../../../libmingw32.a(main.o):(.text.startup+0xc0): undefined reference
to `WinMain#16'
collect2.exe: error: ld returned 1 exit status
[Done] exited with code=1 in 0.747 seconds
Is there anything I'm missing out with all those functions? Essentially I'm a newbie and is there any old version confusions between syntax, formatting, etc...?
Your code missing main function, which starts the program;
and
You must declare you variables before use them;
int main() {
int inum = 0, dnum = 0;
inum++;
dnum--;
std::cout << inum << std::endl;
std::cout << std::pow( 2, 6 );
}

unsigned integer overflow error in gcc(TDM-GCC)?

#include <iostream>
#include <climits>
#include <cinttypes>
using namespace std;
int main()
{
uint16_t i = 0;
cout << USHRT_MAX << '\n' << i - 1 << '\n';
return 0;
}
Output
65535
-1
I expected two equal outputs, but it wasn't. Isn't this a non-standard-compliant behaviour?
*System: Windows7
*Compile Option: g++ -o $(FileNameNoExt) $(FileName) -std=c++11 -Wall -Wextra
When C++ sees the expression
i - 1
it automatically promotes i and 1 to int types, so the result of the expression is an int, hence the output of -1.
To fix this, either cast the overall result of the expression back to uint16_t, or do something like
i--;
to modify i in-place, then print i.
Hope this helps!
i is promoted to an int before the evaluation of i - 1, so the expression i - 1 is itself evaluated as a signed integer (int), try :
cout << USHRT_MAX << '\n' << (uint16_t)(i - 1) << '\n';
Live Demo

Return Pointers With Multiple Value Win32 Linking Error

I have encountered the typical No Entry Point Personality V0 error before and worked around it with: -fno-exceptions. Although this time when I use the workaround cmd crashed and only runs the first cin >> line of the program.
However, I can run the program no problem in MSYS.
I compiled with:
g++ ReturnPointer.cpp -o ReturnPointer.exe (gave error)
g++ ReturnPointer.cpp -o ReturnPointer.exe -fno-exceptions (runs: MSYS Shell Only)
#include <iostream>
short factor(int, int*, int*);
int main()
{
int number, squared, cubed;
short error;
std::cout << "Enter a number (0 - 20 ): ";
std::cin >> number;
error = factor(number, &squared, &cubed);
if (!error)
{
std::cout << "number: " << number << "\n";
std::cout << "square: " << squared << "\n";
std::cout << "cubed: " << cubed << "\n";
}
else
std::cout << "Error encountered!!\n";
return 0;
}
short factor(int n, int* pSquared, int* pCubed)
{
short value = 0;
if (n > 20)
{
value = 1;
}
else
{
*pSquared = n * n;
*pCubed = n * n * n;
value = 0;
}
return value;
}
Granted, this isn't the end of the world. I am just expanding my knowledge on an area of C++ that trips me up a lot. Although, if I were to ever use pointers in this manner in a larger program...that would turn into a mess.
I would just like to know what needs to be done or what I am missing to run this in CMD.

Static Initialization Fiasco - On Purpose

Just for fun, I was investigating the order of dynamic initialization of static objects.
In a file name t.h, I put
struct T {
static std::vector<std::string> me;
static int add(std::string s) { me.push_back(s); return me.size(); }
};
(Plus needed headers for vector and string.)
"std::vector T::me" is in t.cpp.
The file main.cpp prints out the values in T::me:
#include "t.h"
#include <iostream>
using namespace std;
int main()
{
T::me.push_back("main");
cout << "T::me.size()=" << T::me.size() << endl;
for (unsigned i = 0; i<T::me.size(); ++i) {
cout << i << "-" << T::me[i] << endl;
}
return 0;
}
next, I create "a.cpp" and put the following in it:
#include "t.h"
int a = T::add("a");
Do the similar for file b.cpp and c.cpp using "b" and "c" as appropriate.
Compile using g++ *.cpp, then run ./a.out. The order of static initialization from compilation unit to compilation unit is unspecified. In my case it is consistently in reverse alphabetical order. I get:
3 - c
2 - b
1 - a
0 - main
No problems so far.
Now I create u.cpp like a.cpp but using "u". Recompile/rerun, "u" does not show up in the list.
Is it because I never referenced u? I never referenced a,b,c, but I change main:
#include "t.h"
#include <iostream>
using namespace std;
extern int u;
int main()
{
cout << "u=" << u << endl;
T::me.push_back("main");
cout << "T::me.size()=" << T::me.size() << endl;
for (unsigned i = 0; i<T::me.size(); ++i) {
cout << i << "-" << T::me[i] << endl;
}
return 0;
}
The program prints out "u=2", but "u" is not in the list. Shouldn't u have been dynamically initialized before use and, therefore, T::me have been updated to include "u"? I think there should be a better explanation than that u comes after t in the alphabet.
I've got it. Simple, really.
T::me is zero initialized statically according to the rules of C++. There is a constructor, however, to run dynamically. There's no guarantee when that constructor runs. It is apparently - in this case - running after u is initialized.
It seems that the compilation linking order matters:
g++ -o m a.cpp u.cpp t.cpp main.cpp
gives
a=2
u=1
T::me.size()=3
0-u
1-a
2-main
but
g++ -o m main.cpp t.cpp a.cpp u.cpp
gives
a=2
u=1
T::me.size()=1
0-main
and reversing a.cpp and u.cpp in the last case causes a=1 and u=2.
Interesting!