這學(xué)期準(zhǔn)備自學(xué)完這本書税手!1/25/2018 立FLAG為證!
Using File Redirection
$ addItems < infile > outfile
Reference
Reference must be initialized, it cannot be rebinded. A reference is not an object. It is another name(alias) for an existing object.
int ival = 1024;
int &refVal = ival;
refVal = 2; // assigns 2 to ival
Pointer
A pointer is an object. It holds the address of another object. Because references are not objects, they don't have addresses. Hence, we may not define a pointer to reference. Types of the pointer and the object to which it points must match.
Each declarator and relate its variable to the base type differently. For example,
int i = 1024, *p = &i, &r = i;
Here i is an int, p is a pointer, r is a reference. They all relate to the base type int.
Note that int* p
is misleading, because in this statement our base type should be int
rather than int*
. Use int *p
instead.
Since reference is not an object, we may not have a pointer to a reference. However, we can have a reference to a pointer. For example,
int i = 42;
int *p;
int *&r = p; // read from right to left. r is a reference to the pointer p
r = &i; // pointer r/p points to i
*r = 0; // change i to 0
For const pointer, always read from right to left. Consider the following example:
int errNumb = 0;
int *const curErr = &errNumb // curErr is a const pointer to int
const double pi = 3.14159
const double *const pip = &pi // pip is a const pointer to a const double type
void funciton pointer
void pointer can holds the address of any type, but we cannot use a void*
to operate on the object it addresses.
// Example program
#include <iostream>
#include <string>
char glFun(int a) { return '2'; }
int main()
{
char (*pFun)(int);
pFun = glFun;
std::cout << (*pFun)(2);
}
Here pFun is a function pointer, therefore in the declaration (first line) there is a * before pFun. In main, we first assign the address of function glFun to pFun, and then use the deference operator * to get the value.
We could use typedef
to simplify and reuse.
typedef char (*PTRFUN)(int);
PTRFUN pFun;
char glFun(int a){ return '2';}
int main()
{
pFun = glFun;
(*pFun)(2);
}
constexpr
Runtime constants are those whose initialization values can only be resolved at runtime (when your program is running).
Compile-time constants are those whose initialization values can be resolved at compile-time (when your program is compiling).
In most cases, it doesn’t matter whether a constant value is runtime or compile-time. However, there are a few odd cases where C++ requires a compile-time constant instead of a run-time constant (such as when defining the length of a fixed-size array -- we’ll cover this later). Because a const value could be either runtime or compile-time, the compiler has to keep track of which kind of constant it is.
constexpr double gravity (9.8); // ok, the value of 9.8 can be resolved at compile-time
constexpr int sum = 4 + 5; // ok, the value of 4 + 5 can be resolved at compile-time
std::cout << "Enter your age: ";
int age;
std::cin >> age;
constexpr int myAge = age; // not okay, age can not be resolved at compile-time
#include <iostream>
#include <array>
using namespace std;
constexpr int foo(int i)
{
return i + 5;
}
int main()
{
int i = 10;
std::array<int, foo(5)> arr; // OK
foo(i); // Call is Ok
// But...
std::array<int, foo(i)> arr1; // Error
}
作者:藍色
鏈接:https://www.zhihu.com/question/35614219/answer/63798713
來源:知乎
著作權(quán)歸作者所有化戳。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。
那用macro纱皆,比如#define MAX_STUDENTS_PER_CLASS 30
同眯,可以成為一個我們定義const的解決方案嗎绽昼?
First, because macros are resolved by the preprocessor, which replaces the symbolic name with the defined value, #defined symbolic constants do not show up in the debugger (which shows you your actual code). So although the compiler would compile int max_students = numClassrooms * 30;, in the debugger you’d see int max_students = numClassrooms * MAX_STUDENTS_PER_CLASS;. You’d have to go find the definition of MAX_STUDENTS_PER_CLASS in order to know what the actual value was. This can make your programs harder to debug.
Second, #defined values always have file scope (which we’ll talk more about in the section on local and global variables). This means a value #defined in one piece of code may have a naming conflict with a value #defined with the same file later.
In many applications, a given symbolic constant needs to be used throughout your code (not just in one location). These can include physics or mathematical constants that don’t change (e.g. pi or avogadro’s number), or application-specific “tuning” values (e.g. friction or gravity coefficients). Instead of redefining these every time they are needed, it’s better to declare them once in a central location and use them wherever needed. That way, if you ever need to change them, you only need to change them in one place.
There are multiple ways to facilitate this within C++, but the following is probably easiest:
- Create a header file to hold these constants
- Inside this header file, declare a namespace
- Add all your constants inside the namespace (make sure they’re const)
- include the header file wherever you need it
e.g. constants.h:
#ifndef CONSTANTS_H
#define CONSTANTS_H
// define your own namespace to hold constants
namespace constants
{
constexpr double pi(3.14159);
constexpr double avogadro(6.0221413e23);
constexpr double my_gravity(9.2); // m/s^2 -- gravity is light on this planet
// ... other related constants
}
#endif
#include "constants.h"
double circumference = 2 * radius * constants::pi;
extern
const
is local to the file. If we want to share across files, use extern const int v_name
.
decltype - declare type
decltype(f()) sum = x;
相關(guān)資料
HEADER GUARDS
#ifndef MATH_H
#define MATH_H
int getSquareSides()
{
return 4;
}
#endif
HEADER GUARDS prevent the same header file being copied to the code multiple times.
using
using
declaration let us use a name from a namespace without qualifying the name. In general, code inside headers should not contain using
, because header file codes may be coped into a program which doesn't want using
that namespace.
string
string s4(10, 'c'); // cccccccccc
getline(cin,line)
would discard the newline.
vector
vector
is a template, not a type. Types generated from vector must include the element type, for example, vector<int>
.
array
char a[6] = "Daniel"; // this doesn't compile as there is no space for null
char a1[] = "Daniel"; // this works
char a2[] = {'C','\0'} // this works too
int a[] = {0,1,2};
int a1[] = a; // not legal! no initialize/assign between arrays
Define a pointer or reference to an array, we could read inside out - first read the right to get size, then left to get type.
int (*Parray)[10] = &arr; // Parray is a pointer to an array of ten ints
int (&arrRef)[10] = arr; // arrRef is an alias for an arr
int *(&arry)[10] = ptrs; // arry is a reference to ten int pointers
When we use a variable to subscript an array, we normally should define that variable to have type size_t
.
The []
subscript operator in array is the one that is defined as part of the language. The []
subscript operator in vector is defined by library vector
template and applies to operands of type vector
.
Character Arrays Are Special
Character arrays have an additional form of initialization: We can initialize such arrays from a string literal. When we use this form of initialization, it is important to remember that string literals end with a null character. That null character is copied into the array along with the characters in the literal:
char a1[] = {'C', '+', '+'}; // list initialization, no null
char a2[] = {'C', '+', '+', '\0'}; // list initialization, explicit null
char a3[] = "C++"; // null terminator added automatically
const char a4[6] = "Daniel"; // error: no space for the null!
We cannot initialize an array as a copy of another array, nor is it legal to assign one array to another:
int a[] = {0, 1, 2}; // array of three ints
int a2[] = a; // error: cannot initialize one array with another
a2 = a; // error: cannot assign one array to another
Reference: