1、C++中模仿gets是 getline(cin, string object)
#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;
struct CanyBar {
string info; // 存儲匹薩的品牌
double weight; // 披薩的重量
double diameter;; // 披薩的直徑
void showInfomation();
} piSa;
void CanyBar::showInfomation() {
cout << "品牌" << " " << info << endl;
cout << "重量" << " " << weight << endl;
cout << "直徑" << " " << diameter << endl;
}
void work() {
cout << "請輸入披薩的品牌 :";
// getline()
getline(cin, piSa.info);
// cin >> piSa.info;
cout << "請輸入披薩的直徑 :";
cin >> piSa.diameter;
cout << "請輸入披薩的重量 :";
cin >> piSa.weight;
piSa.showInfomation();
}
int main() {
//#ifdef local
// freopen("data.txt", "r", stdin);
//// freopen("data.txt", "w", stdout);
//#endif
work();
return 0;
}
View Code
2、C++的array好像沒什麼用啊,
#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;
void work() {
array<double, 3> a;
double sum = 0;
cout << "請輸入三次40米跑成績" << endl;
for (int i = 0; i < 3; ++i) {
cin >> a[i];
sum += a[i];
}
cout << sum / 3 << endl;
}
int main() {
work();
return 0;
}
3、input file stream ----> ifstream input output stream ---> iostream
#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;
void work() {
ifstream input("data.txt");
char ch;
int ans = 0;
if (input.is_open()) {
string s;
while (!input.eof()) {
input.get(ch);
ans++;
}
input.close();
cout << ans - 2 << endl; //會讀取'\n',
//回車 + 換行 兩個字元
}
}
int main() {
//#ifdef local
// freopen("data.txt", "r", stdin);
//// freopen("data.txt", "w", stdout);
//#endif
work();
return 0;
}
4、要傳回指針,不能用局部變量
// arrfun3.cpp -- array functions and const
#include <iostream>
const int Max = 5;
// function prototypes
int* fill_array(double ar[], int *begin, int *end);
void show_array(const double ar[], int *end); // don't change data
void revalue(double r, double ar[], int *end);
int main() { //要傳回指針,不能用局部變量
using namespace std;
double properties[Max];
int begin = 0, end = 5;
int *size = fill_array(properties, &begin, &end);
show_array(properties, size);
if (*size > 0) {
cout << "Enter revaluation factor: ";
double factor;
while (!(cin >> factor)) { // bad input
cin.clear();
while (cin.get() != '\n')
continue;
cout << "Bad input; Please enter a number: ";
}
revalue(factor, properties, size);
show_array(properties, size);
}
cout << "Done.\n";
// cin.get();
// cin.get();
return 0;
}
int * fill_array(double ar[], int *begin, int *end) {
using namespace std;
double temp;
static int i;
for (i = *begin; i < *end; i++) {
cout << "Enter value #" << (i + 1) << ": ";
cin >> temp;
if (!cin) { // bad input
cin.clear();
while (cin.get() != '\n')
continue;
cout << "Bad input; input process terminated.\n";
break;
} else if (temp < 0) // signal to terminate
break;
ar[i] = temp;
}
return &i; //這個會消失,是以用不了,或者static
}
// the following function can use, but not alter,
// the array whose address is ar
void show_array(const double ar[], int *end) {
using namespace std;
for (int i = 0; i < (*end); i++) {
cout << "Property #" << (i + 1) << ": $";
cout << ar[i] << endl;
}
}
// multiplies each element of ar[] by r
void revalue(double r, double ar[], int *end) {
// cout << (*end) << endl;
for (int i = 0; i < (*end); i++)
ar[i] *= r;
}
5、template <typename T>
模闆不會生成函數的定義,也就是不會生成
void work() {
printf("fff"); // 這樣的具體的函數
}
但是它卻會生成函數定義的方案
template <> void swap(int &, int &); // 顯示具體化
template <> void swap<int>(int &, int &); // 顯示具體化
template void swap(int &, int &); // 顯示執行個體化,少了一個在template後面的<>
title1:編寫一個模闆函數,接受一個類型為T的數組,和一個n表示數組長度
尋找數組中最大值。
template <class T>
T maxn(T *a, int len) {
T mx = a[0];
for (int i = 1; i < len; ++i) mx = max(mx, a[i]);
return mx;
}
需要一個執行個體化,接受一個char *str[]的數組,數組中每一個指針指向一個字元串,然後求出最長的那個字元串。
關鍵是怎麼傳參,先來探讨下二維數組要怎麼傳參
int f[12][N];
void fun(const int f[][N]) {
f[1][0] = 1; // 編譯失敗
printf("%d\n", f[1][0]);
}
①、第二維的大小必須指出,因為,f[1][0]的尋址方式是,*((*(f + 1)) + 0),因為二維數組中,在記憶體裡面也是連續存放的,需要告訴系統,每次 + 1需要跳多遠,就是跳N格。
②、要知道其本質,二維數組的名字,就是一個指向長度為N的一維數組的指針。這樣是得f + 1每次跳N格就好。
是以,是這樣寫
void fun(const int (*f)[N]) {
printf("%d\n", f[1][2]);
}
③、如果你是用int **p = new的,則需要fun(int **p),也就是什麼樣的類型,什麼樣的形參
二維數組傳參
#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;
template <class T>
T maxn(T *a, int len) {
T mx = a[0];
for (int i = 1; i < len; ++i) mx = max(mx, a[i]);
return mx;
}
template <> char * maxn(char *str[], int len) {
char *id = str[0];
int mx = strlen(str[0]);
for (int i = 1; i < len; ++i) {
if (mx < strlen(str[i])) {
mx = strlen(str[i]);
id = str[i];
}
}
return id;
}
int a[22];
char *str[222];
void work() {
for (int i = 0; i < 4; ++i) str[i] = new char[22];
strcpy(str[0], "22");
strcpy(str[1], "23");
strcpy(str[2], "232");
strcpy(str[3], "1");
cout << maxn(str, 4) << endl;
}
int main() {
#ifdef local
freopen("data.txt", "r", stdin);
// freopen("data.txt", "w", stdout);
#endif
work();
return 0;
}
char **str,不是二維數組,他是二級指針,和char *str[]一樣
是以是這樣
char **str;
str = new char *[4]; //先配置設定
for (int i = 0; i < 4; ++i) str[i] = new char[22];
而二維數組 char str[][],對應的是char (*str)[]
int (*p)[22] = new int[33][22]; // 可以
int (*p)[c] = new int[22][c]; // 不可以。形參不可以。
const int c = 22;
int (*p)[c] = new int[22][c]; //可以
#include <bits/stdc++.h>
#include <windows.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;
struct Node {
int w, v; // w物品重量, v是物品體積
Node(int _w, int _v) : w(_w), v(_v) {}
};
int calc_dp(const vector<Node> vc, const int c) { //c是背包容量
int **dp = new int *[vc.size()];
for (int i = 0; i < vc.size(); ++i) dp[i] = new int[c + 1];
// int (*dp)[c + 1] = new int[vc.size()][c + 1]; 這樣不行
for (int i = 0; i < vc.size(); ++i) dp[i][0] = 0;
for (int i = 0; i <= c; ++i) {
if (i >= vc[0].w) dp[0][i] = vc[0].v;
else dp[0][i] = 0;
}
bool *sel = new bool[vc.size()];
for (int i = 0; i < vc.size(); ++i) sel[i] = false;
for (int i = 1; i < vc.size(); ++i) {
for (int j = 0; j <= c; ++j) {
if (j >= vc[i].w) dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - vc[i].w] + vc[i].v);
else dp[i][j] = dp[i - 1][j];
}
}
int tc = c;
for (int i = vc.size() - 1; i >= 1; --i) {
if (dp[i][tc] != dp[i - 1][tc]) {
sel[i] = true;
tc -= vc[i].w;
}
}
if (tc) sel[0] = true;
for (int i = 0; i < vc.size(); ++i) printf("%d ", sel[i]);
printf("\n");
return dp[vc.size() - 1][c];
}
int mxState, mxValue;
void calc_baoli(const vector<Node> vc, int c, int now, int state, int ans) { // calc_baoli(vc, c, 0)
if (now == vc.size()) {
if (mxValue < ans) {
mxValue = ans;
mxState = state;
// printf("%d %d\n", ans, state);
}
return ;
}
calc_baoli(vc, c, now + 1, state, ans);
if (c >= vc[now].w) {
calc_baoli(vc, c - vc[now].w, now + 1, state | (1 << now), ans + vc[now].v);
}
}
int calc_greedy(const vector<Node> vc, int c) { // calc_greedy(vc, c)
vector< pair<double, int> > b;
b.clear();
for (int i = 0; i < vc.size(); ++i) b.push_back(make_pair(1.0 * vc[i].v / vc[i].w, i));
sort(b.begin(), b.end(), greater< pair<double, int> >());
bool *sel = new bool[vc.size()];
for (int i = 0; i < vc.size(); ++i) sel[i] = false;
int ans = 0;
for (int i = 0; i < b.size(); ++i) {
if (c >= vc[b[i].second].w) {
c -= vc[b[i].second].w;
ans += vc[b[i].second].v;
sel[b[i].second] = true;
}
}
for (int i = 0; i < vc.size(); ++i) printf("%d ", sel[i]);
printf("\n");
return ans;
}
void work_dp(vector<Node> vc, int c) {
long long be = clock();
printf("動态規劃的答案: %d 時間: ", calc_dp(vc, c));
long long t = clock() - be;
printf("%lld\n\n", t);
}
void work_greedy(vector<Node> vc, int c) {
long long be = clock();
printf("貪心的答案: %d 時間: ", calc_greedy(vc, c));
long long t = clock() - be;
printf("%lld\n\n", t);
}
void work_baoli(vector<Node> vc, int c) {
long long be = clock();
mxState = 0, mxValue = -1;
calc_baoli(vc, c, 0, 0, 0);
for (int i = 0; i < vc.size(); ++i) {
if (mxState & (1 << i)) {
printf("1 ");
} else printf("0 ");
}
printf("\n");
printf("暴力的答案: %d 時間: ", mxValue);
long long t = clock() - be;
printf("%lld\n\n", t);
}
void work() {
vector<Node> vc;
vc.clear();
int n, c;
srand(time(NULL));
printf("---------請輸入背包容量-------------------\n");
scanf("%d", &c);
printf("---------請輸入物品個數-------------------\n");
scanf("%d", &n);
printf("---------請輸入%d個物品-------------------\n", n);
for (int i = 0; i < n; ++i) {
int w, v;
w = rand() % 10 + 1;
v = rand() % 20 + 1;
printf("%d %d\n",w,v);
vc.push_back(Node(w, v));
}
work_dp(vc, c);
work_greedy(vc, c);
work_baoli(vc, c);
}
int main() {
//#ifdef local
// freopen("data.txt", "r", stdin);
//// freopen("data.txt", "w", stdout);
//#endif
work();
return 0;
}
函數調用時候選擇的優先級
1、完全比對,但正常函數優于模闆
2、提升轉換,char和short自動去int, float自動去double
3、标準轉換,int 轉為 char, long 轉為 double
4、使用者定義的轉換
6、在函數中的形參放入const,隻是一個修飾符,表明這個形參是不可以變化的,不是定義一個不可變化的常量一樣。
是以當我們傳入參數進去的時候,不用以為const也是可變的。這裡的const和const int a = 1, //a不可變,是不同的。
和重載運算符那個一樣的。
再比如strcmp(const char * str, const char * sub) // 這個稱謂常量指針,確定這個指針不能修改那塊記憶體的東西,但是卻可以改變這個指針指向的記憶體位置。 “傳入來的指針就算變了指向,和一開始的也是沒關系的
相當于我把家裡的鑰匙複制一份給你,你把他扔了,和我無關”
還有一個就是指針常量, int * const p = &a,說明這個指針的指向不能再改變。
指針常量和常量指針
1、模闆函數、或者模闆類需要在.h檔案下給出函數的定義,因為在其他一個cpp裡面,隻include了它的.h檔案,是以如果你隻是聲明了的話,在cpp裡面就無法找到它的定義,也就是無法按照模闆生成一個具體的函數了,這樣做編譯的時候沒問題,連接配接程式的時候會失敗。
解決方案
1、include file2.cpp,這個操作很騷
2、在file2.cpp中來一個顯式執行個體化,但是這就違背了模闆的作用,難道你為每一個都顯式執行個體化嗎。也好,分為int和double兩種而已。
3、在.h中給出定義(最優), STL也是這麼用
https://zhidao.baidu.com/question/1946414924223767268.html
-------------------------2017年12月22日 21:01:30--------------------------------------------------
輸入的東西會放去緩沖區,比如輸入兩個string1, string2可以cin >> s1, cout << s1, cin >> s2,也是可以得。
就是asb sba
這樣可以兩個串都同時得到。
用cin.sync(); 可以清除緩沖區,這樣第二個字元串就輸入不了了。或者fflush(stdin)
javascript:void(0)
注意用cin.get(str, 6, 結束符),隻能最多讀取5個字元,因為有一個是回車,而且他不接受回車,讓它留在緩沖區、
--------------------------------------2018-1-4 14:19:13-------------------------------------------------------------
如果一個函數是傳回一個引用,這個時候就要注意了,因為傳回引用的話,calc(val) = 2是可以直接指派的,這樣在if的時候可能會出錯
雖然我覺得if那裡很難寫錯,可能以後熬夜寫代碼會寫錯。
是以,應該考慮下是否要放回const的引用。
1 int & calc(int val) {
2 int ans = 0;
3 while (val / 10 > 0) {
4 ans += val % 10;
5 val /= 10;
6 }
7 ans += val;
8 return ans;
9 }
沒傳回const,危險
重載運算符的時候,我剛才在重載 = 這個運算符,這個運算符應該是在裡面搞事。
先說說重載會怎樣。
比如重載了+号,那麼a + c就會退化成a.operator+(c),調用這樣的一個函數。
然後a = a + c,傳回一個一模一樣類型的值給a,是以a的值有改變。。。。
我剛才也一樣,重載了 = ,也是傳回一個一模一樣的類型值,以為a = c也會傳回一個一模一樣的值給a,實則不然。
這其實相當于a.operator=(c),然後就沒了,他不是a = a.operator=(c),就算是這樣,也是徒勞,遞歸一次就知道這是錯的。
是以重載 = 應該是在裡面搞事,在裡面就改了a的值了。而重載其他的 + 之類的,直接重載即可。
再一次解釋,因為它一般會這樣用,a = a + c這樣退化成a = a.operator+(c);,這樣傳回一個一模一樣的類型,指派給a,是可以得。