解决方案:
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>
using namespace std;
class String {
private:
char* str1, * str2;
char* str;
public:
String(char* s1, char* s2);
void Dele();
void Sort();
void Show();
~String() { delete[]str1; delete[]str2; delete[]str; }
};
String::String(char* s1, char* s2) {
str1 = new char[strlen(s1) + 1];
strcpy(str1, s1);
str2 = new char[strlen(s2) + 1];
strcpy(str2, s2);
str = new char[strlen(s1) + strlen(s2) + 1];
strcpy(str, s1);
strcat(str, s2);
}
void String::Dele() {
char* ptr1 = str, * ptr2 = str;
while (*ptr1 != NULL) {
if (*ptr1 != ' ') {
*ptr2 = *ptr1;
ptr2 = ptr2 + 1;
}
ptr1 = ptr1 + 1;
}
*ptr2 = '\0';
}
void String::Sort() {
char* ptr = str;
while (*ptr != NULL) {
char* p = ptr + 1;
while (*p != NULL) {
if (*p < *ptr) {
char Temp = *p;
*p = *ptr;
*ptr = Temp;
}
p = p + 1;
}
ptr = ptr + 1;
}
}
void String::Show() {
cout << "str1 = " << str1 << endl;
cout << "str2 = " << str2 << endl;
cout << "str = " << str << endl;
}
int main() {
char s1[] = "db a", s2[] = "4 1";
String Test = String(s1, s2);
Test.Show();
Test.Dele();
Test.Sort();
Test.Show();
return 0;
}
本题的做题感悟和长进:
第一:strcat()函数 & strcpy()函数
介绍字符串函数:strcat(str1, str2);
功能:把str2衔接在str1的后面
返回值:把str1的首地址返回
注意点:
~ 1.str1必须是带’\0’的字符串,只能是字符型数组,可以是空串。
~ 2.str2可以是字符数组,也可是字符串常量。
~ 3.str1必须足够大。
介绍字符串函数:strcpy(str1, str2);
功能:把str2复制给str1,注意不能用等号赋值
返回值:str1的首地址
注意点:
~ 1.拷贝时连同’\0’一起拷贝
~ 2.str1必须足够大
第二:char* str & char str[]的区别
首先要说明的一点:
C语言操作字符串,是通过字符串的首地址进行的。而一旦获得了首地址,我们能做那些操作呢?首先输出,我们知道有这种操作:printf("%s", str);
,这就是已知首地址就可以进行的。然后,通过把首地址赋给指针,通过指针操作字符串。可以把首地址赋予给不同的指针,进行复杂的运算,比如上述的除去空格、排序……等等。
第二:str[] 是什么?它是字符数组!
如果我们已知这个字符数组:str[] = “Hello World!”,那么这个str就对应着这个字符串所在的首地址,这个字符串在生命周期内,地址是不会发生变化的,所以从指针的角度来说,它的地址是不变的。但是地址里的值可以改变。
第三:*str 是什么?它是一个指针!
指针是什么?声明指针是为了声明指针所指向的内容的数据类型,这里是char类型的指针,说明str指向的地址存放的值是char类型的。而str是一个指针变量,它本身的数据类型是整形,无论它指向的地址的值是什么类型,因为地址是整形,它是地址。而指针变量指向哪个地址是不确定的,所以我们可以进行如下的赋值操作:
char str1[] = "hello";
char* str2 = st1;
这个操作是正确的!而反之则不可以!因为str1[]一旦确定,它的地址就不会变化,如果把另外一个地址赋予给它,就语法错误了!
第三:字符串的结束标识:
字符串一定是以’\0’结尾的字符数组,但是字符数组不一定是字符串!!
而从指针指向的地址的值来看,字符串的结尾既可以是’\0’又可以是NULL
这个题描述很有问题:
第一:维组->一维数组
第二:判断n是否为到数->是否为质数(mdzz)
解决方案:
#include <iostream>
using namespace std;
class Array {
private:
int* p, k;
double* s;
public:
Array(int* ptr, int n);
int Fun(int n);
void Sum();
void Show();
~Array() { delete[] p; delete s; }
};
Array::Array(int* ptr, int n) {
k = n;
p = new int[k + 1];
for (int i = 1; i <= k; ++i)
p[i] = ptr[i - 1];
s = new double(0);
}
int Array::Fun(int n) {
if (n < 2)
return 0;
for (int i = 2; i * i <= n; ++i)
if (0 == n % i)
return 0;
return 1;
}
void Array::Sum() {
int cnt = 0;
for(int i = 0;i < k;++i)
if (Fun(p[i]))
{
cnt++;
*s = *s + p[i];
}
*s = *s / cnt;
}
void Array::Show() {
cout << "数组的元素为:" << endl;
for (int i = 1; i <= k; ++i) {
cout << p[i] << ' ';
if (0 == i % 5)
cout << endl;
}
cout << endl << "质数的平均数为:" << endl;
cout << *s << endl;
}
int main() {
int a[] = { 5,2,7,4,8,23,65,1,40 };
Array arr(a, 9);
arr.Sum();
arr.Show();
return 0;
}
第六题:
这道题呢,我想变一变,多训练指针操作,所以我们把这个字符串原本要求是用字符数组标识,我们改成用指针操作。
解决方案:
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>
using namespace std;
class STR {
private:
char* str1, * str2;
char* str;
public:
STR(char* s1, char* s2) {
str1 = new char[strlen(s1) + 1];
strcpy(str1, s1);
str2 = new char[strlen(s2) + 1];
strcpy(str2, s2);
str = new char[strlen(str1) + strlen(str2) + 1];
}
void ConSort() {
strcpy(str, str1);
strcat(str, str2);
char* ptr1 = str;
while (*ptr1) {
char* ptr2 = (ptr1 + 1);
while (*ptr2) {
if (*ptr1 > *ptr2) {
char Temp = *ptr2;
*ptr2 = *ptr1;
*ptr1 = Temp;
}
ptr2 = ptr2 + 1;
}
ptr1 = ptr1 + 1;
}
}
void Show() {
cout << "str1 = " << str1 << endl;
cout << "str2 = " << str2 << endl;
cout << "连接并且排序后的str = " << str << endl;
}
~STR() { delete[] str1; delete[]str2; delete[]str; }
};
int main() {
char a[80] = { '\0' }, b[80] = { '\0' };
cin >> a >> b;
STR Test = STR(a, b);
Test.ConSort();
Test.Show();
return 0;
}