C++程序设计教程 (钱能)第三章习题

C++程序设计教程 (钱能)第三章 练习3

  • 1.打印-1234567的二进制位码。
  • 2.分别输出各类型的字长和位长。
  • 3.创建向量,用数组初值初始化,求该向量标准差。
  • 4.汇总每个月25号的天数,若是加班日,该天*2。
  • 5.加密与解密字符串。
  • 6.遍历数组的5种方法。
  • 7.将程序中的指针改为引用,实现交换。

1.打印-1234567的二进制位码。

【分析】暂未搞懂,后续更新。

【代码】(我是占位的)

2.分别输出各类型的字长和位长。

【方法1】

bool a = 0;
char b = 'A';
int c = 2;
long int d = 1;
float e = 3;
double f = 4;
long double g = 5;
cout << setw(15)<<"bool:" << sizeof(a) << " byte  " << 8 * sizeof(a) << " bits" << endl;
cout << setw(15) << "char:" << sizeof(b) << " byte  " << 8 * sizeof(b) << " bits" << endl;
cout << setw(15) << "int:" << sizeof(c) << " byte  " << 8 * sizeof(c) << " bits" << endl;
cout << setw(15) << "long int:" << sizeof(d) << " byte  " << 8 * sizeof(d) << " bits" << endl;
cout << setw(15) << "float:" << sizeof(e) <<    " byte  " << 8 * sizeof(e) << " bits" << endl;
cout << setw(15) << "double:" << sizeof(f) << " byte  " << 8 * sizeof(f) << " bits" << endl;
cout << setw(15) << "long double:" << sizeof(g) << " byte  " << 8 * sizeof(g) << " bits" << endl;

/*
运行结果:
	   bool:1 byte  8 bits
	   char:1 byte  8 bits
		int:4 byte  32 bits
   long int:4 byte  32 bits
	  float:4 byte  32 bits
	 double:8 byte  64 bits
long double:8 byte  64 bits
*/

【方法2】

void print(char * tName, int tLen) {
	cout << setw(15) << tName << ":" << tLen << "bye " << tLen * 8 << "bits\n";
}
int main(){
	print("bool", sizeof(bool));
	print("char", sizeof(char));
	print("int", sizeof(int));
	print("long int", sizeof(long int));
	print("float", sizeof(float));
	print("double", sizeof(double));
	print("long double", sizeof(long double));
}
//运行结果同上

3.创建向量,用数组初值初始化,求该向量标准差。

【方法1】

int a[] = { 6,3,7,1,4,8,2,9,11,5 };
vector<int> va(a, a + 10);
double sum = 0, sum1 = 0;
for (int i = 0; i < va.size(); i++) {
	sum += va[i];
}
double mean = sum / 10;
for (int i = 0; i < va.size(); i++) {
	sum1 += pow((va[i] - mean),2);
}
double s = sqrt(sum1 / 10);
cout << "标准差为:" << s << endl;

//标准差为:3.03974

【方法2】

int a[] = { 6,3,7,1,4,8,2,9,11,5 };
int n = sizeof(a) / sizeof(a[0]);
vector<int> va(a, a + n);
double sigma = 0,pSigma = 0;
for (int i = 0; i < va.size(); i++) {
	int v = va[i];
	sigma += v;
	pSigma += v*v;
}
sigma /= n;
cout << "标准差:" << sqrt(pSigma / n - sigma*sigma);
//将方差化简可得到这个公式
//标准差为:3.03974

4.汇总每个月25号的天数,若是加班日,该天*2。

abc.txt
Oct. 25 2003
Oct. 26 2003
Sep. 12 2003*
Juy. 25 2002*
App. 25 2004

【方法1】依次读入月份、日期和年份。

ifstream in("abc.txt");
int count = 0, day;
for (string month,year; in >> month>>day>>year; ) {		
	if (day == 25)
		count += year.length() - 3;	//没*加1,有*加2				
}
cout << "每个月25号的天数:" << count << endl;

//每个月25号的天数:4

【方法2】字符串查找

ifstream in("abc.txt");
int sum = 0;
string s;
while (getline(in,s)) {
	if (s.find("25") != string::npos)
		if (s.find("*") != string::npos)
			sum += 2;
		else
			sum++;
}	
cout << "每个月25号的天数:" << sum << endl;

//每个月25号的天数:4

      string::find()函数:是一个字符或字符串查找函数,该函数有唯一的返回类型,即string::size_type,即一个无符号整型类型,可能是整数也可能是长整数。
      如果查找成功,返回按照查找规则找到的第一个字符或者子串的位置;如果查找失败,返回string::npos,即-1。
static const size_type npos = -1;

5.加密与解密字符串。

      将输入的一行字符以加密形式输出,然后将其解密,解密字符序列与输入的正文进行比较,吻合时输出解密的正文,否则输出失败。
【方法1】

//ASCII中的0~31为控制字符;32~126为打印字符;127为Delete(删除)命令。
const char key[] = "4962873";
string encode(string & str) {
	string result(str);
	for (int i = 0; i < result.length(); i++) {
		result[i] += key[i % 7] - '0';
		if (result[i] > 'z') {
			result[i] -= 91;
			//若加上数字后,超过122,则减去91,
			//保证最终落在32(' ')到122('z')区间内。
			//如123 - 91 = 32 ,减完91之后能保证落在32-122的区间内
		}
	}
	return result;
}
//解码函数做编码函数的反操作
string decode(string & str) {
	string result(str);
	for (int i = 0; i < result.length(); i++) {
		result[i] -= key[i % 7] - '0';
		if (result[i] < ' ') {
			result += 91;
		}
	}
	return result;
}

int main() {
	string s;
	getline(cin, s);
	string t = encode(s);
	cout << t << "\n";
	cout << (s == decode(t) ? s + "\n" : string("decode failed!\n"));
}

/*
运行结果:
	the result of 3 and 2 is not 8
	xqk"zlvyuz"wm#7)gpl'5$ry"vvw$A
	the result of 3 and 2 is not 8	
*/

【方法2】这个方法有问题,暂未解决。
str = new char[];
问题:C3078 必须在新的表达式中指定数组大小

const int key[] = { 4,9,6,2,8,7,3 };
char *str, *str1, *str2;
str = new char[30];	
//输入的字符长度为30,故给定30,不指定长度或指定大于30的长度会出错
cout << "明文:" ;
cin.getline(str, 100);
const int n = strlen(str);//strlen(str)计算给定字符串的长度
str1 = new char[n];//本没有指定长度,这样会出错
str2 = new char[n];//本没有指定长度,这样会出错
for (int i = 0; i < n; i++) {
	*(str1 + i) = *(str + i) + key[i % 7];
	if ((int)str1[i] > 122)
		*(str1 + i) = *(str1 + i) % 90 + 32;
}		
cout << "密文:" << str1 << endl;//C-串可直接用数组名输出内容

for (int j = 0; j < n; j++) {
	*(str2 + j) = *(str1 + j) - key[j % 7];
	if ((int)str2[j] < ' ')
		*(str2 + j) = *(str2 + j) - 32 + 90;
}

if (*str2 == *str)
	cout << "解密后的正文:" << str2 << endl;
else
	cout << "解密失败!" << endl;

/*
	明文:the result of 3 and 2 is not 8
	密文:xqk"zlvyuz"wm#7)gpl'5$ry"vvw$A
	解密后的正文:the result of 3 and 2 is not 8

*/

6.遍历数组的5种方法。

int sum[5] = { 0 };//存放每种方法的结果
int iArray[] = { 1,4,2,7,13,32,21,48,16,30 };
int size = sizeof(iArray) / sizeof(*iArray);//计算数组长度
int * iPtr = iArray;
for (int i = 0; i < size; i++)
{
	sum[3] += iPtr[i];
}
for (int i = 0; i < size; i++)
{
	sum[2] += *(iPtr + i);
}
for (int i = 0; i < size; i++)
{//  1)* 与 ++ 是同优先级。
 //  2)两者结合性都是从右向左。
 //  3)故 iPtr++ 先做,因为是后增,故先取值再自增,所以iPtr与*结合的同时,也自增。
	sum[1] += *iPtr++;
}
for (int i = 0; i < size; i++)
{
	sum[0] += iArray[i];
}
for (int i = 0; i < size; i++)
{
	sum[4] += *(iArray + i);
}
for (int i = 0; i < 5; i++) {
	cout << "sum["<<i<<"]:"<<sum[i] << " " << endl;
}

/*
运行结果:
	sum[0]:174
	sum[1]:174
	sum[2]:174
	sum[3]:174
	sum[4]:174
*/

注:int a[] = { 1,2,3 };
       cout << sizeof(a) << endl;//a数组的字节数是12
       cout << *a << endl;//第一个元素的值为1

7.将程序中的指针改为引用,实现交换。

void mySwap(int* a, int* b) {
	int temp = *a;
	*a = *b;
	*b = temp;
}
int main() {
	int a = 16, b = 48;
	cout << "a = " << a << " ,b = " << b << endl;
	mySwap(&a, &b);//指针
	cout << "After Being Swapped:" << endl;
	cout << "a = " << a << " ,b = " << b << endl;
}

/*
	运行结果:
		a = 16 ,b = 48
		After Being Swapped:
		a = 48 ,b = 16
*/
void mySwap1(int& a, int& b) {
	int temp = a;
	a = b;
	b = temp;
}
int main() {
	int a = 16, b = 48;
	cout << "a = " << a << " ,b = " << b << endl;
	mySwap1(a, b);//引用
	cout << "After Being Swapped:" << endl;
	cout << "a = " << a << " ,b = " << b << endl;
}

/*
	运行结果:
		a = 16 ,b = 48
		After Being Swapped:
		a = 48 ,b = 16
*/	
void mySwap2(int  a, int  b) {
	int temp = a;
	a = b;
	b = temp;
}
int main() {
	int a = 16, b = 48;
	cout << "a = " << a << " ,b = " << b << endl;
	mySwap2(a, b);//不会交换a和b的值
	cout << "After Being Swapped:" << endl;
	cout << "a = " << a << " ,b = " << b << endl;
}

/*	
	运行结果:
		a = 16 ,b = 48
		After Being Swapped:
		a = 16 ,b = 48
*/

分析:

       因为mySwap2(int a, int b)被调用时,实参进行副本初始化,函数并没有访问调用传递的实参本身,因而也不会修改实参的值。也就是说函数被调用时传入的是x,y的值,而不是它们的地址。
       只有传入地址才能在函数调用时通过地址真正改变两个数的值。否则就只是改变了函数栈帧里创建的形参,这样当函数完成调用时,栈帧里面创建的形参就会随之消失,无法完成交换。

你可能感兴趣的:(C++,C++程序设计教程,钱能)