1008. Elevator (20)

1.该题较为简单,主要是给出一串电梯停留的层数,求出花费的总时间。

The highest building in our city has only one elevator. A request list is made up with N positive numbers. The numbers denote at which floors the elevator will stop, in specified order. It costs 6 seconds to move the elevator up one floor, and 4 seconds to move down one floor. The elevator will stay for 5 seconds at each stop.

For a given request list, you are to compute the total time spent to fulfill the requests on the list. The elevator is on the 0th floor at the beginning and does not have to return to the ground floor when the requests are fulfilled.

Input Specification:

Each input file contains one test case. Each case contains a positive integer N, followed by N positive numbers. All the numbers in the input are less than 100.

Output Specification:

For each test case, print the total time on a single line.

Sample Input:

3 2 3 1

Sample Output:

41

AC代码:


//#include<string>
//#include <iomanip>
#include<vector>
#include <algorithm>
//#include<stack>
#include<set>
#include<queue>
#include<map>
//#include<unordered_set>
//#include<unordered_map>
//#include <sstream>
//#include "func.h"
//#include <list>
#include<stdio.h>
#include<iostream>
#include<string>
#include<memory.h>
#include<limits.h>
using namespace std;
int main(void)
{
	int n;
	while (scanf("%d", &n) != EOF)
	{
		int *request = new int[n + 1];
		request[0] = 0;
		int sum = n * 5;
		for (int i = 1; i <= n; i++)
		{
			scanf("%d", &request[i]);
			int diff = request[i] - request[i - 1];
			if (diff < 0) sum += -diff * 4;//注意是负号
			else sum += diff * 6;
		}
		cout << sum << endl;
	}
	return 0;
}

1007. Maximum Subsequence Sum (25)

1.题目要求最大的连续自序列和,如果全为负数,则输出0,首位,末位;如果不为负数,则输出总和,子序列的第一位,子序列的最后一位。

2.注意判断全为负数的情况,第一个数是否为负数,不要漏判断。(刚开始漏判断了)

3.实际上采用动态规划,dp[i]=max{dp[i-1]+num[i],num[i]},dp[i]一定会包含当前的数字num[i],但是可以简化为判断dp[i-1]是否为负数。

Given a sequence of K integers { N1, N2, …, NK }. A continuous subsequence is defined to be { Ni, Ni+1, …, Nj } where 1 <= i <= j <= K. The Maximum Subsequence is the continuous subsequence which has the largest sum of its elements. For example, given sequence { -2, 11, -4, 13, -5, -2 }, its maximum subsequence is { 11, -4, 13 } with the largest sum being 20.

Now you are supposed to find the largest sum, together with the first and the last numbers of the maximum subsequence.

Input Specification:

Each input file contains one test case. Each case occupies two lines. The first line contains a positive integer K (<= 10000). The second line contains K numbers, separated by a space.

Output Specification:

For each test case, output in one line the largest sum, together with the first and the last numbers of the maximum subsequence. The numbers must be separated by one space, but there must be no extra space at the end of a line. In case that the maximum subsequence is not unique, output the one with the smallest indices i and j (as shown by the sample case). If all the K numbers are negative, then its maximum sum is defined to be 0, and you are supposed to output the first and the last numbers of the whole sequence.

Sample Input:

10
-10 1 2 3 4 -5 -23 3 7 -21

Sample Output:

10 1 4
//#include<string>
//#include <iomanip>
#include<vector>
#include <algorithm>
//#include<stack>
#include<set>
#include<queue>
#include<map>
//#include<unordered_set>
//#include<unordered_map>
//#include <sstream>
//#include "func.h"
//#include <list>
#include<stdio.h>
#include<iostream>
#include<string>
#include<memory.h>
using namespace std;
int main(void) {

	int n;
	cin >> n;
	if (n == 0)
	{
		cout << "0 0 0" << endl;
		return 0;
	}
	long long *num = new long long[n];
	for (int i = 0; i < n; i++)
	{
		cin >> num[i];
	}
	//使用pair,first代表从那个i开始,second表示从i加到当前数字的综合
	vector<pair<int, long long>> dp(n, { 0, 0 });
	dp[0].first = 0;
	dp[0].second = num[0];
	bool negative = true;
	if (num[0] >= 0) negative = false;//注意第一个数也要判断正负
	for (int i = 1; i < n; i++)
	{
		if (negative&&num[i] >= 0) negative = false;//判断是否全负数
		if (dp[i - 1].second <= 0)
		{//如果dp[i-1]小于0,那么num[i]加上它肯定小于num[i],所以不加
			dp[i].first = i;
			dp[i].second = num[i];
		}
		else
		{//如果dp[i-1]大于等于0,那么num[i]加上它肯定大于等于num[i],所以需要加上
			dp[i].first = dp[i - 1].first;
			dp[i].second = dp[i - 1].second + num[i];
		}

	}

	if (negative)
	{//如果全为负数,则输出首尾两个数
		cout << 0 << " " << num[0] << " " << num[n - 1] << endl;
	}
	else
	{
		long long maxAns = -1; int index = -1;
		for (int i = 0; i < n; i++)
		{//遍历一遍,找出second最大的dp
			if (maxAns < dp[i].second)
			{
				maxAns = dp[i].second;
				index = i;
			}
		}
		//根据题目要求输出最大的和,和相当一序列起始值和结束值
		cout << dp[index].second << " " << num[dp[index].first] << " " << num[index] << endl;
	}

	return 0;
}

1006. Sign In and Sign Out (25)

1.采用algorithm.h里面的sort函数,对时间进行排序,需要重写比较函数。
2.计算最早到时,通过到达时间前后进行排序。
3.计算最晚走时,通过离开时间的晚早进行排序。

At the beginning of every day, the first person who signs in the computer room will unlock the door, and the last one who signs out will lock the door. Given the records of signing in’s and out’s, you are supposed to find the ones who have unlocked and locked the door on that day.

Input Specification:

Each input file contains one test case. Each case contains the records for one day. The case starts with a positive integer M, which is the total number of records, followed by M lines, each in the format:

ID_number Sign_in_time Sign_out_time

where times are given in the format HH:MM:SS, and ID number is a string with no more than 15 characters.

Output Specification:

For each test case, output in one line the ID numbers of the persons who have unlocked and locked the door on that day. The two ID numbers must be separated by one space.

Note: It is guaranteed that the records are consistent. That is, the sign in time must be earlier than the sign out time for each person, and there are no two persons sign in or out at the same moment.

Sample Input:

3
CS301111 15:30:28 17:00:10
SC3021234 08:00:00 11:25:25
CS301133 21:45:00 21:58:40

Sample Output:

SC3021234 CS301133
//#include<string>
//#include <iomanip>
#include<vector>
#include <algorithm>
//#include<stack>
#include<set>
#include<queue>
#include<map>
//#include<unordered_set>
//#include<unordered_map>
//#include <sstream>
//#include "func.h"
//#include <list>
#include<stdio.h>
#include<iostream>
#include<string>
#include<memory.h>
using namespace std;
int time2Int(string s)
{
	int hour = (s[0] - '0') * 10 + s[1] - '0';
	int min = (s[3] - '0') * 10 + s[4] - '0';
	int sec = (s[6] - '0') * 10 + s[7] - '0';
	return hour * 3600 + min * 60 + sec;
}
struct people{
	int begin, end;
	string ID;
	people() :begin(0), end(0), ID(""){};
};
bool cmpBegin(const people&a, const people&b)
{
	if (a.begin < b.begin) return true;
	else return false;
}
bool cmpEnd(const people&a, const people&b)
{
	if (a.end > b.end) return true;
	else return false;
}
int main(void) {

	int n;
	cin >> n;
	vector<people> p(n);
	for (int i = 0; i < n; i++)
	{
		string a, b, c;
		cin >> a >> b >> c;
		p[i].ID = a;
		p[i].begin = time2Int(b);
		p[i].end = time2Int(c);
	}
	string first = "";
	sort(p.begin(), p.end(), cmpBegin);
	first = p[0].ID;
	sort(p.begin(), p.end(), cmpEnd);
	string last = p[0].ID;
	cout << first << " " << last << endl;
	return 0;
}

1005. Spell It Right (20)

1.主要是string的位操作,string的每一位都是一个char

Given a non-negative integer N, your task is to compute the sum of all the digits of N, and output every digit of the sum in English.

Input Specification:

Each input file contains one test case. Each case occupies one line which contains an N (<= 10100).

Output Specification:

For each test case, output in one line the digits of the sum in English words. There must be one space between two consecutive words, but no extra space at the end of a line.

Sample Input:

12345

Sample Output:

one five

 

//#include<string>
//#include <iomanip>
#include<vector>
#include <algorithm>
//#include<stack>
#include<set>
#include<queue>
#include<map>
//#include<unordered_set>
//#include<unordered_map>
//#include <sstream>
//#include "func.h"
//#include <list>
#include<stdio.h>
#include<iostream>
#include<string>
#include<memory.h>
using namespace std;

int main(void) {

	string str;
	cin >> str;
	int sum = 0;
	for (int i = 0; i < str.size(); i++)
	{
		sum += str[i] - '0';//直接进行各位的累加
	}
	string int2Str[10] = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" };

	str = "";
	string ans = "";
	if (sum == 0) ans = "zero";
	while (sum != 0)
	{
		char c = sum % 10 + '0';
		str = c + str;
		sum /= 10;
	}
	for (int i = 0; i < str.size(); i++)
	{
		ans += int2Str[str[i] - '0'];
		if (i != str.size() - 1)
			ans += " ";
	}
	cout << ans << endl;


	return 0;
}

 

1004. Counting Leaves (30)

1.题目要求计算家族树中,每层叶子节点的数量(即没有后代的人的个数)。

2.可为多叉树,采用vector<string>保存子树名称。

3.采用map记录树节点。

4.采用广度遍历,输出每层的叶子节点数量。

节点代码如下:

struct node{
	vector<string> child;
	int head;
	string ID;
	node() :head(-1), child(0), ID(""){};
};

A family hierarchy is usually presented by a pedigree tree. Your job is to count those family members who have no child.

Input

Each input file contains one test case. Each case starts with a line containing 0 < N < 100, the number of nodes in a tree, and M (< N), the number of non-leaf nodes. Then M lines follow, each in the format:

ID K ID[1] ID[2] ... ID[K]

where ID is a two-digit number representing a given non-leaf node, K is the number of its children, followed by a sequence of two-digit ID’s of its children. For the sake of simplicity, let us fix the root ID to be 01.

Output

For each test case, you are supposed to count those family members who have no child for every seniority level starting from the root. The numbers must be printed in a line, separated by a space, and there must be no extra space at the end of each line.

The sample case represents a tree with only 2 nodes, where 01 is the root and 02 is its only child. Hence on the root 01 level, there is 0 leaf node; and on the next level, there is 1 leaf node. Then we should output “0 1” in a line.

Sample Input

2 1
01 1 02

Sample Output

0 1

AC代码:

//#include<string>
//#include <iomanip>
#include<vector>
#include <algorithm>
//#include<stack>
#include<set>
#include<queue>
#include<map>
//#include<unordered_set>
//#include<unordered_map>
//#include <sstream>
//#include "func.h"
//#include <list>
#include<stdio.h>
#include<iostream>
#include<string>
#include<memory.h>
using namespace std;
#define maxDist 999999
struct node{
	vector<string> child;
	int head;
	string ID;
	node() :head(-1), child(0), ID(""){};
};

int main(void) {

	int n, m;
	cin >> n >> m;

	map<string, node> tree;
	for (int i = 0; i < m; i++)
	{//循环输入父子关系
		string ID;
		cin >> ID;
		tree[ID].ID = ID;
		int k;
		cin >> k;
		for (int i = 0; i < k; i++)
		{
			string tmp;
			cin >> tmp;
			if (tmp.size() == 1)
				tmp = "0" + tmp;//避免出现单位的数字如1,2,3,4;题目要求是两位数,所以是01,02,03,04
			tree[ID].child.push_back(tmp);
			tree[tmp].ID = tmp;
			tree[tmp].head++;
		}
	}
	//需要建立一个前头节点,便于循环计算
	tree["superhead"].ID = "";
	tree["superhead"].child = vector<string>(0);
	tree["superhead"].head = 100;
	string headID = "";
	tree["superhead"].child.push_back("01");
	headID = "superhead";
	queue<string> q;
	q.push(headID);
	vector<int> ans(0);
	int count1 = 1;
	int count2 = 0;
	int leaf = 0;
	while (!q.empty())
	{
		for (int k = 0; k < count1; k++)
		{//上一层有count1个
			string top = q.front();
			q.pop();
			for (int i = 0; i < tree[top].child.size(); i++)
			{
				string tmp = tree[top].child[i];
				if (tree[tmp].child.size() == 0)
					leaf++;//如果没有子节点,那么就是叶子节点
				else
				{
					q.push(tmp);//有子节点,压进队列,继续遍历
					count2++;
				}
			}
		}
		ans.push_back(leaf);
		leaf = 0;
		count1 = count2;
		count2 = 0;
	}
	for (int i = 0; i < ans.size(); i++)
	{
		cout << ans[i];
		if (i != ans.size() - 1)
			cout << " ";
	}
	return 0;
}

1003. Emergency (25)

1.求源城市s到目标城市t的最小耗费路径,如果路径不唯一,则输出具有最多救援队的路径。

2.采用dijkstra算法,算出最小耗费cost。

3.利用最小耗费cost最为约束条件,进行深度搜索DFS(循环->锁->dfs->解锁)。

As an emergency rescue team leader of a city, you are given a special map of your country. The map shows several scattered cities connected by some roads. Amount of rescue teams in each city and the length of each road between any pair of cities are marked on the map. When there is an emergency call to you from some other city, your job is to lead your men to the place as quickly as possible, and at the mean time, call up as many hands on the way as possible.

Input

Each input file contains one test case. For each test case, the first line contains 4 positive integers: N (<= 500) – the number of cities (and the cities are numbered from 0 to N-1), M – the number of roads, C1 and C2 – the cities that you are currently in and that you must save, respectively. The next line contains N integers, where the i-th integer is the number of rescue teams in the i-th city. Then M lines follow, each describes a road with three integers c1, c2 and L, which are the pair of cities connected by a road and the length of that road, respectively. It is guaranteed that there exists at least one path from C1 to C2.

Output

For each test case, print in one line two numbers: the number of different shortest paths between C1 and C2, and the maximum amount of rescue teams you can possibly gather.
All the numbers in a line must be separated by exactly one space, and there is no extra space allowed at the end of a line.

Sample Input

5 6 0 2
1 2 1 5 3
0 1 1
0 2 2
0 3 1
1 2 1
2 4 1
3 4 1

Sample Output

2 4

AC代码:

//#include<string>
//#include <iomanip>
#include<vector>
#include <algorithm>
//#include<stack>
#include<set>
#include<queue>
#include<map>
//#include<unordered_set>
//#include<unordered_map>
//#include <sstream>
//#include "func.h"
//#include <list>
#include<stdio.h>
#include<iostream>
#include<string>
#include<memory.h>
using namespace std;
#define maxDist 999999
struct vertexNode{
	vector<int> list;
	bool visited, sured;
	int pre;
	int cost;
};
struct cmp{
	bool operator()(const pair<int, int>&a, const pair<int, int>&b)
	{
		return a.second > b.second;
	}
};

void dfs(int now, int&target, vertexNode *v, int **w, int*rescue, vector<bool>&used, int &minCost, vector<int>&ans, int nowCost, int rescueTeam)
{
	if (now == target&&minCost == nowCost)
	{
		ans.push_back(rescueTeam);
	}
	else
	{
		for (int i = 0; i < v[now].list.size(); i++)
		{
			int q = v[now].list[i];
			if (!used[q] && nowCost + w[now][q] <= minCost)
			{//以最小耗费为约束条件
				used[q] = true;
				dfs(q, target, v, w, rescue, used, minCost, ans, nowCost + w[now][q], rescueTeam + rescue[q]);
				used[q] = false;
			}
		}
	}
}

int main(void) {

	int n, m, s, t;
	cin >> n >> m >> s >> t;

	int *rescue = new int[n];
	int *cost = new int[n];

	for (int i = 0; i < n; i++)
	{
		scanf("%d", &rescue[i]);//输出各城市的救援队数目
		cost[i] = 99999999;//初始化cost
	}

	int **w = new int*[n];

	vertexNode *v = new vertexNode[n];
	for (int i = 0; i < n; i++)
	{
		w[i] = new int[n];
		memset(w[i], 0, sizeof(w[i]));
		v[i].cost = 99999999;
		v[i].pre = -1;
		v[i].list = vector<int>(0);
		v[i].sured = false;
		v[i].visited = false;
	}

	for (int i = 0; i < m; i++)
	{
		int a, b, weight;
		scanf("%d %d %d", &a, &b, &weight);
		v[a].list.push_back(b);
		v[b].list.push_back(a);
		w[a][b] = weight;
		w[b][a] = weight;
	}

	v[s].visited = true;
	v[s].pre = -1;
	v[s].cost = 0;
	while (1)
	{//采用dijkstra算法计算最小耗费
		int p = -1;
		for (int i = 0; i < n; i++)
		{
			if (p == -1 && v[i].visited&&!v[i].sured)
				p = i;
			else if (p != -1 && v[i].visited&&!v[i].sured&&v[p].cost > v[i].cost)
				p = i;
		}
		if (p == -1) break;
		v[p].sured = true;
		for (int i = 0; i < v[p].list.size(); i++)
		{
			int q = v[p].list[i];
			if (!v[q].visited)
			{
				v[q].cost = v[p].cost + w[p][q];
				v[q].visited = true;
				v[q].pre = p;
			}
			else if (v[q].visited&&!v[q].sured&&v[q].cost > v[p].cost + w[p][q])
			{
				v[q].cost = v[p].cost + w[p][q];
				v[q].visited = true;
				v[q].pre = p;
			}
		}
	}
	int minCost = v[t].cost;
	vector<bool> used(n, false);
	vector<int> ans(0);
	used[s] = true;
	dfs(s, t, v, w, rescue, used, minCost, ans, 0, rescue[s]);

	sort(ans.begin(), ans.end());
	cout << ans.size() << " " << ans.back() << endl;

	return 0;
}

1002. A+B for Polynomials (25)

1.直接建立1001长度的数组,分别进行存储,最后累加输出。

This time, you are supposed to find A+B where A and B are two polynomials.

Input

Each input file contains one test case. Each case occupies 2 lines, and each line contains the information of a polynomial: K N1 aN1 N2 aN2 … NK aNK, where K is the number of nonzero terms in the polynomial, Ni and aNi (i=1, 2, …, K) are the exponents and coefficients, respectively. It is given that 1 <= K <= 10,0 <= NK < … < N2 < N1 <=1000.

Output

For each test case you should output the sum of A and B in one line, with the same format as the input. Notice that there must be NO extra space at the end of each line. Please be accurate to 1 decimal place.

Sample Input

2 1 2.4 0 3.2
2 2 1.5 1 0.5

Sample Output

3 2 1.5 1 2.9 0 3.2

 

AC代码:

//#include<string>
//#include<stack>
//#include<unordered_set>
//#include <sstream>
//#include "func.h"
//#include <list>
#include <iomanip>
#include<unordered_map>
#include<set>
#include<queue>
#include<map>
#include<vector>
#include <algorithm>
#include<stdio.h>
#include<iostream>
#include<string>
#include<memory.h>
#include<limits.h>
#include<stack>
using namespace std;

int main(void)
{
	vector<float> N1(1002, 0);
	vector<float> N2(1002, 0);
	int n, m;
	cin >> n;
	//输入第一个多项式
	for (int i = 0; i < n; i++)  
	{
		int idx = 0;        
		cin >> idx;
		cin >> N1[idx];
	}

	cin >> m;
	//输入第二个多项式
	for (int i = 0; i < m; i++)  
	{
		int idx = 0;        
		cin >> idx;
		cin >> N2[idx];
	}

	//同阶的系数相加
	for (int i = 0; i < N1.size(); i++)
	{
		N1[i] = N1[i] + N2[i];
	}

	int sum = 0;
	for (int i = 0; i < N1.size(); i++)
	{
		if (N1[i] != 0)
			sum++;
	}
	cout << sum;  
	for (int i = N1.size() - 1; i >= 0; i--)
	{//高位先输出
		if (N1[i] != 0)//不为0,则输出
			printf(" %d %.1f", i, N1[i]);
	}
	return 0;
}

1001. A+B Format (20)

1.主要是字符串处理,然后插入逗号

2.注意正负数

3.输入可以直接使用int类型读取

Calculate a + b and output the sum in standard format — that is, the digits must be separated into groups of three by commas (unless there are less than four digits).

Input

Each input file contains one test case. Each case contains a pair of integers a and b where -1000000 <= a, b <= 1000000. The numbers are separated by a space.

Output

For each test case, you should output the sum of a and b in one line. The sum must be written in the standard format.

Sample Input

-1000000 9

Sample Output

-999,991

 

AC代码

//#include<string>
//#include<stack>
//#include<unordered_set>
//#include <sstream>
//#include "func.h"
//#include <list>
#include <iomanip>
#include<unordered_map>
#include<set>
#include<queue>
#include<map>
#include<vector>
#include <algorithm>
#include<stdio.h>
#include<iostream>
#include<string>
#include<memory.h>
#include<limits.h>
#include<stack>
using namespace std;

int main(void)
{
	int a, b;
	cin >> a >> b;
	int result = a + b;
	bool sign = true;//正负符号标志位
	if (result < 0)
	{
		result = -result;
		sign = false;
	}
	string str = "";
	if (result == 0) str = "0";
	while (result != 0)
	{//转化成string
		char c = result % 10 + '0';
		str += c;
		result /= 10;
	}

	//此时的str是倒序的
	string output = "";
	for (int i = 0; i < str.size() - 1; i++)
	{
		output = str[i] + output;
		if ((i+1) % 3 == 0)
			output = ',' + output;
	}
	output = str[str.size() - 1] + output;
	if (!sign) output = "-" + output;
	cout << output << endl;

	return 0;
}

134 Gas Station(Medium)

1.在做pat的to fill or not to fill的时候想起同样是加油站的题目,于是翻出来复习一下
2.关键在于理解潜在的条件。假设油量为tank,如果到了当前站i,tank<0,即不能到达站i+1,那么起始站start和i之间的任何一个站i都不能到达站i+1。因为每个站至少贡献了0或者>0的油量,去掉一个站,那么tank必然比现在的油量还要小,所以更加不可能达到i+1.

证明:
设tank[a,b]是指以a为起始站,到达b站后,油箱的油量。
如果上述2结论不成立,则可以推导出,在start与i之间的某一个站j,使得tank[j,i]>tank[start,i],又tank[start,i]=tank[start,j]+tank[j,i],那么推得tank[start,j]<0,
而车能够从start走到i,所以对于任意k属于[start,i],均有tank[start,k]>=0,与tank[start,j]<0矛盾,所以2结论是正确的。

There are N gas stations along a circular route, where the amount of gas at station i is gas[i].

You have a car with an unlimited gas tank and it costs cost[i] of gas to travel from station i to its next station (i+1). You begin the journey with an empty tank at one of the gas stations.

Return the starting gas station’s index if you can travel around the circuit once, otherwise return -1.

Note:
The solution is guaranteed to be unique.

Subscribe to see which companies asked this question

AC代码:

class Solution {
public:
    int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
        int tank=0;//当前的油箱油量
        int start=0;//从第0个站开始计算,后面也作为结果进行返回
        int n=gas.size();
        for(int i=0;i<gas.size();i++)
        {//遍历所有加油站
            tank+=gas[(i+start)%n]-cost[(i+start)%n];//更新油箱的油量
            if(tank<0)
            {//如果tank小于0,表明没办法从i走到下一个油站,那么start直接从下一站开始
            //如果无法从start达到i,那么start和i之间任何一个站都不能达到i,因为每个站至少贡献了0和>=0的油量
                start=i+start+1;//start从当前i站的下一个站开始
                i=-1;//使得下次从i=0开始
                if(start>=n)
                {//已经把所有情况都遍历了,仍不能满足要求
                    return -1;
                }
                tank=0;
            }
        }
        return start;
    }
};

C/C++中extern关键字详解

转自:http://www.cnblogs.com/yc_sunniwell/archive/2010/07/14/1777431.html

基本解释:extern可以置于变量或者函数前,以标示变量或者函数的定义在别的文件中提示编译器遇到此变量和函数时在其他模块中寻找其定义。此外extern也可用来进行链接指定。

      也就是说extern有两个作用,第一个,当它与"C"一起连用时,如: extern "C" void fun(int a, int b);则告诉编译器在编译fun这个函数名时按着C的规则去翻译相应的函数名而不是C++的,C++的规则在翻译这个函数名时会把fun这个名字变得面目全非,可能是fun@aBc_int_int#%$也可能是别的,这要看编译器的"脾气"了(不同的编译器采用的方法不一样),为什么这么做呢,因为C++支持函数的重载啊,在这里不去过多的论述这个问题,如果你有兴趣可以去网上搜索,相信你可以得到满意的解释!
    第二,当extern不与"C"在一起修饰变量或函数时,如在头文件中: extern int g_Int; 它的作用就是声明函数或全局变量的作用范围的关键字,其声明的函数和变量可以在本模块活其他模块中使用,记住它是一个声明不是定义!也就是说B模块(编译单元)要是引用模块(编译单元)A中定义的全局变量或函数时,它只要包含A模块的头文件即可,在编译阶段,模块B虽然找不到该函数或变量,但它不会报错,它会在连接时从模块A生成的目标代码中找到此函数。

2 问题:extern 变量
  在一个源文件里定义了一个数组:char a[6];
  在另外一个文件里用下列语句进行了声明:extern char *a;
  请问,这样可以吗? 
  答案与分析:
  1)、不可以,程序运行时会告诉你非法访问。原因在于,指向类型T的指针并不等价于类型T的数组。extern char *a声明的是一个指针变量而不是字符数组,因此与实际的定义不同,从而造成运行时非法访问。应该将声明改为extern char a[ ]
  2)、例子分析如下,如果a[] = "abcd",则外部变量a=0x61626364 (abcd的ASCII码值),*a显然没有意义
  显然a指向的空间(0x61626364)没有意义,易出现非法内存访问。
  3)、这提示我们,在使用extern时候要严格对应声明时的格式,在实际编程中,这样的错误屡见不鲜。
  4)、extern用在变量声明中常常有这样一个作用,你在*.c文件中声明了一个全局的变量,这个全局的变量如果要被引用,就放在*.h中并用extern来声明

3 问题:单方面修改extern 函数原型
  当函数提供方单方面修改函数原型时,如果使用方不知情继续沿用原来的extern申明,这样编译时编译器不会报错。但是在运行过程中,因为少了或者多了输入参数,往往会照成系统错误,这种情况应该如何解决?
  答案与分析:
  目前业界针对这种情况的处理没有一个很完美的方案,通常的做法是提供方在自己的xxx_pub.h中提供对外部接口的声明,然后调用方include该头文件,从而省去extern这一步。以避免这种错误。
  宝剑有双锋,对extern的应用,不同的场合应该选择不同的做法。

4 问题:extern “C”
  在C++环境下使用C函数的时候,常常会出现编译器无法找到obj模块中的C函数定义,从而导致链接失败的情况,应该如何解决这种情况呢?

  答案与分析:
  C++语言在编译的时候为了解决函数的多态问题,会将函数名和参数联合起来生成一个中间的函数名称,而C语言则不会,因此会造成链接时找不到对应函数的情况,此时C函数就需要用extern “C”进行链接指定,这告诉编译器,请保持我的名称,不要给我生成用于链接的中间函数名。
  下面是一个标准的写法:
//在.h文件的头上
#ifdef __cplusplus
#if __cplusplus
extern "C"{
 #endif
 #endif /* __cplusplus */ 
 …
 …
 //.h文件结束的地方
 #ifdef __cplusplus
 #if __cplusplus
}
#endif
#endif /* __cplusplus */ 

5 问题:extern 函数声明
  常常见extern放在函数的前面成为函数声明的一部分,那么,C语言的关键字extern在函数的声明中起什么作用?
  答案与分析:
  如果函数的声明中带有关键字extern,仅仅是暗示这个函数可能在别的源文件里定义,没有其它作用。即下述两个函数声明没有明显的区别:
extern int f(); 和int f();
  当然,这样的用处还是有的,就是在程序中取代include “*.h”来声明函数,在一些复杂的项目中,我比较习惯在所有的函数声明前添加extern修饰。关于这样做的原因和利弊可见下面的这个例子:“用extern修饰的全局变量”

    (1) 在test1.h中有下列声明:
    #ifndef TEST1H
    #define TEST1H
    extern char g_str[]; // 声明全局变量g_str
    void fun1();
    #endif
    (2) 在test1.cpp中
    #include "test1.h"
        char g_str[] = "123456"; // 定义全局变量g_str
        void fun1() { cout << g_str << endl; }
    (3) 以上是test1模块, 它的编译和连接都可以通过,如果我们还有test2模块也想使用g_str,只需要在原文件中引用就可以了
    #include "test1.h"

     void fun2()    { cout << g_str << endl;    }
    以上test1和test2可以同时编译连接通过,如果你感兴趣的话可以用ultraEdit打开test1.obj,你可以在里面找到"123456"这个字符串,但是你却不能在test2.obj里面找到,这是因为g_str是整个工程的全局变量,在内存中只存在一份,test2.obj这个编译单元不需要再有一份了,不然会在连接时报告重复定义这个错误!
    (4) 有些人喜欢把全局变量的声明和定义放在一起,这样可以防止忘记了定义,如把上面test1.h改为
    extern char g_str[] = "123456"; // 这个时候相当于没有extern
    然后把test1.cpp中的g_str的定义去掉,这个时候再编译连接test1和test2两个模块时,会报连接错误,这是因为你把全局变量g_str的定义放在了头文件之后,test1.cpp这个模块包含了test1.h所以定义了一次g_str,而test2.cpp也包含了test1.h所以再一次定义了g_str,这个时候连接器在连接test1和test2时发现两个g_str。如果你非要把g_str的定义放在test1.h中的话,那么就把test2的代码中#include "test1.h"去掉换成:
    extern char g_str[];
    void fun2()   {  cout << g_str << endl;   }
   这个时候编译器就知道g_str是引自于外部的一个编译模块了,不会在本模块中再重复定义一个出来,但是我想说这样做非常糟糕,因为你由于无法在test2.cpp中使用#include "test1.h",那么test1.h中声明的其他函数你也无法使用了,除非也用都用extern修饰,这样的话你光声明的函数就要一大串,而且头文件的作用就是要给外部提供接口使用的,所以请记住, 只在头文件中做声明,真理总是这么简单

6. extern 和 static

 (1) extern 表明该变量在别的地方已经定义过了,在这里要使用那个变量.
 (2) static 表示静态的变量,分配内存的时候, 存储在静态区,不存储在栈上面.

    static 作用范围是内部连接的关系, 和extern有点相反.它和对象本身是分开存储的,extern也是分开存储的,但是extern可以被其他的对象用extern 引用,而static 不可以,只允许对象本身用它. 具体差别首先,static与extern是一对“水火不容”的家伙,也就是说extern和static不能同时修饰一个变;其次,static修饰的全局变量声明与定义同时进行,也就是说当你在头文件中使用static声明了全局变量后,它也同时被定义了;最后,static修饰全局变量的作用域只能是本身的编译单元,也就是说它的“全局”只对本编译单元有效,其他编译单元则看不到它,如:
    (1) test1.h:
    #ifndef TEST1H
    #define TEST1H
    static char g_str[] = "123456"; 
    void fun1();
    #endif

    (2) test1.cpp:
    #include "test1.h"
    void fun1()  {   cout << g_str << endl;  }
    (3) test2.cpp
    #include "test1.h"
    void fun2()  {   cout << g_str << endl;  }
    以上两个编译单元可以连接成功, 当你打开test1.obj时,你可以在它里面找到字符串"123456",同时你也可以在test2.obj中找到它们,它们之所以可以连接成功而没有报重复定义的错误是因为虽然它们有相同的内容,但是存储的物理地址并不一样,就像是两个不同变量赋了相同的值一样,而这两个变量分别作用于它们各自的编译单元。 也许你比较较真,自己偷偷的跟踪调试上面的代码,结果你发现两个编译单元(test1,test2)的g_str的内存地址相同,于是你下结论static修饰的变量也可以作用于其他模块,但是我要告诉你,那是你的编译器在欺骗你,大多数编译器都对代码都有优化功能,以达到生成的目标程序更节省内存,执行效率更高,当编译器在连接各个编译单元的时候,它会把相同内容的内存只拷贝一份,比如上面的"123456", 位于两个编译单元中的变量都是同样的内容,那么在连接的时候它在内存中就只会存在一份了,如果你把上面的代码改成下面的样子,你马上就可以拆穿编译器的谎言:
    (1) test1.cpp:
    #include "test1.h"
    void fun1()
    {
        g_str[0] = ”a”;
        cout << g_str << endl;
    }

    (2) test2.cpp
    #include "test1.h"
    void fun2()  {  cout << g_str << endl;  }
    (3) void main()     {
        fun1(); // a23456
        fun2(); // 123456
    }
    这个时候你在跟踪代码时,就会发现两个编译单元中的g_str地址并不相同,因为你在一处修改了它,所以编译器被强行的恢复内存的原貌,在内存中存在了两份拷贝给两个模块中的变量使用。正是因为static有以上的特性,所以一般定义static全局变量时,都把它放在原文件中而不是头文件,这样就不会给其他模块造成不必要的信息污染,同样记住这个原则吧!

7. extern 和const

   C++中const修饰的全局常量据有跟static相同的特性,即它们只能作用于本编译模块中,但是const可以与extern连用来声明该常量可以作用于其他编译模块中, 如extern const char g_str[];
    然后在原文件中别忘了定义:     const char g_str[] = "123456"; 

    所以当const单独使用时它就与static相同,而当与extern一起合作的时候,它的特性就跟extern的一样了!所以对const我没有什么可以过多的描述,我只是想提醒你,const char* g_str = "123456" 与 const char g_str[] ="123465"是不同的, 前面那个const 修饰的是char *而不是g_str,它的g_str并不是常量,它被看做是一个定义了的全局变量(可以被其他编译单元使用), 所以如果你像让char*g_str遵守const的全局常量的规则,最好这么定义const char* const g_str="123456".