C/C++ 练习题及答案

时间:2023-02-23 23:59:30

习题来自于互联网和书籍!

1、利用指针编写交换两个整型变量值的函数。程序的运行结果如下:

输入:5,6 输出:6,5


注释:网上很多写法都是交换变量的内容,现在提供一个写法交换地址的。
#include <cstdlib>
#include <iostream>

int changeInt(int** source, int** dest)
{
int ret = 0;
if (source == nullptr || dest == nullptr)
{
ret = -1;
printf_s("Error: changeInt(int* source, int* dest) source == nullptr || dest == nullptr errCode:%d", ret);
return ret;
}

int*temp = *source;

*source = *dest;

*dest = temp;

return ret;
}

void main()
{
int a = 5, b = 6;
int* pa = &a; int* pb = &b;
printf_s("*pa = %d; *pb = %d \n", *pa, *pb);
int ret = changeInt(&pa, &pb);
if (ret == 0){
printf_s("*pa = %d; *pb = %d \n", *pa, *pb);
}
system("pause");
}

2、编写一个函数,输入一个字符串,然后将这个字符串反序输出。

输入:ABCDEF 输出:FEDCBA


//不改变源数组
int reverseString(const char* const source, char* dest)
{
int ret = 0;
if (source == nullptr || dest == nullptr)
{
ret = -1;
return ret;
}
const char* p = source;
//求出source的长度
int len = strlen(p);
//指向源数组尾元素
p = source + len - 1;
//指向目标数组头元素
char* pd = dest;
//递减源数组指针步长,并将值付给目标数组
while (len > 0)
{
*pd = *p;
pd++;
p--;
len--;
}
//最后要加上字符串结束符
*pd = '\0';
return ret;
}

//改变源数组
int reverseString2(char* source)
{
int ret = 0;
if (source == nullptr)
{
ret = -1;
return ret;
}
//指向数组头元素
char* p1 = source;
int len = strlen(source);
// 指向数组尾元素
char* p2 = source + len - 1;
//临时储存拷贝过来的值
char temp;
//每次增加P1,减少P2
while (p1 < p2)
{
temp = *p2;
*p2 = *p1;
*p1 = temp;
p1++;
p2--;
}
return ret;
}
void main()
{
//test reverseString
char source[10] = { "123456" };
char dest[10];
reverseString(source, dest);
printf_s("%s \n",dest);//654321

//test reverseString2
reverseString2(source);
printf_s("%s \n",source);//654321

system("pause");
}

3、替换字符串指定子字符串的内容。

输入:"xxxabcxxxabcxx"  替换abc 为 33333 输出:"xxx33333xxx33333xx"


//soure 源字符串
//subStr 要被替换的内容
//replaceStr 替换后的字符串
//dest 输出字符串
int replaceString(const char* const source, const char* const subStr, const char* const replaceStr, char* dest)
{
int ret = 0;
if (source == nullptr)
{
ret = -1;
return ret;
}

char *temp = dest;
char *pt = temp;

//先查找有没有subStr
const char* s = source;
const char* pFind = NULL;

//如果有则用dest替换掉subStr并将新字符串拷贝到temp空间中
do
{
//1、先检查是否找到指定值
pFind = strstr(s, subStr);
if (pFind == nullptr)
{
break;
}
//2、先pt指向到temp的最后面
pt = temp + strlen(temp);
//3、拷贝查找后之前的字符到临时空间
memcpy(pt, s, pFind - s);
//4、链接需要替换的字符
/*strcat_s(temp, 100, replaceStr);*///不能使用strcat_s,会添加一个'\0'
pt = temp + strlen(temp);//再次指到temp的末尾
memcpy(pt, replaceStr, strlen(replaceStr));//分配内存
//5、改变pf和s的值
pFind = pFind + strlen(subStr);
s = pFind;
} while (*s != '\0' && subStr != nullptr);
//6、链接尾字符
pt = temp + strlen(temp);//再次指到temp的末尾
memcpy(pt, s, source + strlen(source) - s);//分配内存

return ret;
}

void main()
{
char source[100] = "xxxabcxxxabcxx";
char dest1[100] = {0};
char dest2[100] = { 0 };
replaceString(source, "abc", "33333",dest1);
printf_s("%s\n", dest1);
replaceString(source, "abc", "z", dest2);
printf_s("%s\n", dest2);
/*char source[100] = "xxxabcxxxabcxx";
char temp[100] = { 0 };
memcpy(temp, source, 3);
printf_s("%s\n", temp);
memcpy(temp+strlen(temp), source + 3, 3);
printf_s("%s\n", temp);*/
system("pause");

4、去除字符串的首尾空白字符。

输入:"   abc   ", 输出:"abc"

//去除字符串首尾的空白字符(改变源字符串)
int trim(char* source)
{
int ret = 0;
if (source == nullptr || *source == '\0')
{
return ret;
}
//指向数组头元素
char* pb = source;
//指向数组尾元素(-1)是安全的,因为已经判断source不会为0
char* pe = source + strlen(source) - 1;
int len;
//从头开始检测遇到不是空格停下来
while (*pb == ' ' && *pb != '\0')
{
pb++;
}
//从尾开始检测遇到不是空格停下来
while (*pe == ' ' && pe != source)
{
pe--;
}
//如果全是空格就全部删除,否则拷贝不是空格的部分
if (pe < pb)
{
*source = '\0';
}
else
{
len = pe - pb + 1;
memcpy(source, pb, len);
*(source + len) = '\0';
}

return ret;
}
void main()
{
/*char source[20] = " 123456 ";
trim(source);
printf_s("%s\n", source);//123456
char source2[20] = " a";
trim(source2);
printf_s("%s\n", source2);//
char source2[20] = "";
trim(source2);
printf_s("%s\n", source2);//
char source2[20] = "ac ";
trim(source2);
printf_s("%s\n", source2);//ac/
char source2[20] = "avc";
trim(source2);
printf_s("%s\n", source2);//abc*/
system("pause");
}

5、定义一个结构体,要求从键盘输入数据,并且可以通过某个字段排序,并打印出结构体内容。(结构体内不要含有指针)

//定义结构体
typedef struct MyStruct
{
char name[32];
char title[32];
int age;
char addr[128];
}Mystruct;

//结构体输入
Mystruct* importMyStruct(int num)
{
MyStruct* m = (MyStruct*)malloc(num*sizeof(MyStruct));
if (m == nullptr)
{
return nullptr;
}
memset(m, 0, sizeof(MyStruct));
for (size_t i = 0; i < num; i++)
{
printf_s("请输入姓名: ");
cin >> m[i].name;//此处用scanf_s会报错,无法写入内存,求解释
printf_s("请输入头衔: ");
cin >> m[i].title;
printf_s("请输入年龄: ");
cin >> m[i].age;
printf_s("请输入地址: ");
cin >> m[i].addr;
}
return m;
}
//释放结构体数组
void freeMyStruct(MyStruct* pM)
{
if (pM != nullptr)
{
free(pM);
}
}
//打印结构体
void printMyStruct(const MyStruct* pM, int num)
{
if (pM == nullptr)
{
return;
}
for (size_t i = 0; i < num; i++)
{
printf_s("姓名是: %s\n", pM[i].name);
printf_s("头衔是: %s\n", pM[i].title);
printf_s("年龄是: %d\n", pM[i].age);
printf_s("地址是: %s\n", pM[i].addr);
}
}
//排序结构体
void sortMyStructsByName(MyStruct* pMList, int num)
{
if (pMList == nullptr || num <= 0)
{
return;
}
MyStruct temp;
for (size_t i = 0; i < num; i++)
{
for (size_t j = i+1; j < num; j++)
{
if (pMList[i].age < pMList[j].age)
{
temp = pMList[i];
pMList[i] = pMList[j];
pMList[j] = temp;
}
}
}
}

void main()
{
MyStruct* t = nullptr;
t = importMyStruct(5);
cout << "排序之前打印:" << endl;
printMyStruct(t, 5);
cout << "排序之后打印:" << endl;
sortMyStructsByName(t, 5);
printMyStruct(t, 5);
if (t != nullptr)
{
freeMyStruct(t);
t = nullptr;
}
system("pause");
}

6、定义一个结构体,要求从键盘输入数据,并且可以通过某个字段排序,并打印出结构体内容。(结构体内含有指针)

注释:和题目5一样,只是分配内存和释放内存的地方改变了。只贴出改变代码

//结构体输入
Mystruct* importMyStruct(int num)
{
MyStruct* m = (MyStruct*)malloc(num*sizeof(MyStruct));
if (m == nullptr)
{
return nullptr;
}
memset(m, 0, sizeof(MyStruct));
for (size_t i = 0; i < num; i++)
{
m[i].name = (char*)malloc(32 * sizeof(char));
memset(m[i].name, 0, 32 * sizeof(char));
m[i].title = (char*)malloc(32 * sizeof(char));
memset(m[i].title, 0, 32 * sizeof(char));
m[i].addr = (char*)malloc(128 * sizeof(char));
memset(m[i].addr, 0, 128 * sizeof(char));

printf_s("请输入姓名: ");
cin >> m[i].name;//此处用scanf_s会报错,无法写入内存,求解释
printf_s("请输入头衔: ");
cin >> m[i].title;
printf_s("请输入年龄: ");
cin >> m[i].age;
printf_s("请输入地址: ");
cin >> m[i].addr;
}
return m;
}

//释放结构体数组
void freeMyStruct(MyStruct* pM, int num)
{
if (pM == nullptr)
{
return;
}
for (size_t i = 0; i < num; i++)
{
if (pM[i].name != nullptr)
{
free(pM[i].name);
pM[i].name == nullptr;
}
if (pM[i].title != nullptr)
{
free(pM[i].title);
pM[i].title == nullptr;
}
if (pM[i].addr != nullptr)
{
free(pM[i].addr);
pM[i].addr == nullptr;
}
}

if (pM != nullptr)
{
free(pM);
}
}

7、合并两个字符数组并且排序。

输入:char* a[10] = { "hello", "what", "is","your","name" };
char b[10][30] = {"how","old","are","you"};

输出:char** p = {"are",  "hello",  "how",  "is"  ,"name",  "old",  "what",  "you",  "your"}

char** sortMergeArray(char** pa, int numa, char (*pb)[30], int numb, int* numc)
{
int len = numa + numb;
int i = 0;
char** pTmp = (char**)malloc(len*sizeof(char*));
for (i = 0; i < len; i++)
{
pTmp[i] = (char*)malloc(30 * sizeof(char));
memset(pTmp[i], 0, 30 * sizeof(char));
}

for (i = 0; i < numa; i++)
{
strcpy_s(pTmp[i], 30, pa[i]);
}
for ( i = numa; i < len; i++)
{
strcpy_s(pTmp[i], 30, pb[i - numa]);
}

char* temp = (char*)malloc(30 * sizeof(char));
for (int n = 0; n < len; n++)
{
for (int m = n + 1; m < len; m++)
{
if (strcmp(pTmp[n], pTmp[m]) > -1){
strcpy_s(temp, 30, pTmp[n]);
strcpy_s(pTmp[n], 30, pTmp[m]);
strcpy_s(pTmp[m], 30, temp);
}
}
}

free(temp);
temp = nullptr;
*numc = len;
return pTmp;
}

int freeMergeArray(char** p, int num)
{
int ret = 0;
int i = 0;
if (p == nullptr)
{
ret = -1;
return ret;
}

for (i = 0; i < num; i++)
{
if (p[i] == nullptr)
{
continue;
}
free(p[i]);
p[i] = nullptr;
}

free(p);
p = nullptr;
return ret;
}

void main()
{
char* a[10] = { "hello", "what", "is","your","name" };
char b[10][30] = {"how","old","are","you"};
int num = 0, i = 0;

char** p = sortMergeArray(a, 5, b, 4, &num);

for (i = 0; i < num; i++)
{
printf("%s ", p[i]);
}
printf("Sort....\n");
system("pause");
}
//直接修改int sortMergeArray_2(char** pa, int numa, char(*pb)[30], int numb, char***pc,int* numc){int len = numa + numb;int i = 0;char** pTmp = (char**)malloc(len*sizeof(char*));for (i = 0; i < len; i++){pTmp[i] = (char*)malloc(30 * sizeof(char));memset(pTmp[i], 0, 30 * sizeof(char));}for (i = 0; i < numa; i++){strcpy_s(pTmp[i], 30, pa[i]);}for (i = numa; i < len; i++){strcpy_s(pTmp[i], 30, pb[i - numa]);}char* temp = (char*)malloc(30 * sizeof(char));for (int n = 0; n < len; n++){for (int m = n + 1; m < len; m++){if (strcmp(pTmp[n], pTmp[m]) > -1){strcpy_s(temp, 30, pTmp[n]);strcpy_s(pTmp[n], 30, pTmp[m]);strcpy_s(pTmp[m], 30, temp);}}}free(temp);temp = nullptr;*numc = len;*pc = pTmp;return 0;}

8、编写一个链表,要求实现创建链表,销毁链表,增加节点,删除节点,打印链表,逆置链表功能。

#include <cstdlib>
#include <iostream>

typedef struct _Node
{

int data;
_Node* next;

}Node;

Node* createList();
int destroyList(Node* pHead);
int insertBeforeNode(Node* pHead, int search,int data);
int delNode(Node* pHead, int data);
int printList(Node* pHead);
int reverseList(Node* pHead);

int reverseList(Node* pHead)
{
int ret = 0;
if (pHead == nullptr || pHead->next == nullptr || pHead->next->next == nullptr)
{
ret = -1;
return ret;
}

Node* pPre = pHead->next, *pCrt = pHead->next->next, *pTemp;

while (pCrt != nullptr)
{
pTemp = pCrt->next;
pCrt->next = pPre;
pPre = pCrt;
pCrt = pTemp;
}

pHead->next->next = nullptr;
pHead->next = pPre;

return ret;
}

int destroyList(Node* pHead)
{
int ret = 0;
if (pHead == nullptr)
{
ret = -1;
return ret;
}

Node* pCrt = pHead;
Node* pTmp = nullptr;
while (pCrt != nullptr)
{
pTmp = pCrt->next;

free(pCrt);

pCrt = pTmp;
}

return ret;
}

int delNode(Node* pHead, int data)
{
int ret = 0;
if (pHead == nullptr)
{
ret = -1;
return ret;
}
Node* pPre = pHead;
Node* pCrt = pHead->next;

while (pCrt != nullptr)
{
if (pCrt->data == data)
{
break;
}
pPre = pCrt;
pCrt = pCrt->next;
}

if (pCrt == nullptr)
{
ret = -2;
return ret;
}

pPre->next = pCrt->next;
free(pCrt);

return ret;
}

int insertBeforeNode(Node* pHead, int search, int data)
{
int ret = 0;
if (pHead == nullptr)
{
ret = -1;
return ret;
}
Node* pPre = pHead;
Node* pCrt = pHead->next;
Node* pM = nullptr;
while (pCrt != nullptr)
{
if (search == pCrt->data)
{
break;
}
pPre = pCrt;
pCrt = pCrt->next;
}

pM = (Node*)malloc(sizeof(Node));
pM->data = data;
pM->next = pCrt;
pPre->next = pM;

return ret;
}

int printList(Node* pHead)
{
int ret = 0;
Node* p = pHead->next;

std::cout << "( ";
while (p != nullptr)
{
printf_s("%d ", p->data);
p = p->next;
}
std::cout << " )" << std::endl;
return ret;
}

Node* createList()
{
int data = 0;
Node* pHead = (Node*)malloc(sizeof(Node));
Node* pCrt = pHead,*pM;
if (pHead == nullptr)
{
return nullptr;
}
pHead->data = 0;
pHead->next = nullptr;

do{
std::cout << "intput Node(-1 to end): ";
std::cin >> data;
if (data == -1)
{
break;
}
pM = (Node*)malloc(sizeof(Node));
pM->data = data;
pM->next = nullptr;

pCrt->next = pM;
pCrt = pM;
} while (data != -1);

return pHead;
}
void main()
{
Node*pHead = createList();
printList(pHead);

insertBeforeNode(pHead, 20,19);
printList(pHead);

delNode(pHead, 19);
printList(pHead);

reverseList(pHead);
printList(pHead);

destroyList(pHead);
system("pause");
}

9、操作符重载练习。要求实现[]、==、!=、=

#ifndef __ARRAY_H__
#define __ARRAY_H__

class IntArray
{
public:
IntArray(int len);
IntArray(const IntArray& a);
~IntArray();
int getData(int index)const;
void setData(int index, int value);
int length()const;
IntArray& operator=(const IntArray& a);
int& operator[](int i)const;
bool operator==(const IntArray& a);
bool operator!=(const IntArray& a);
private:
int mLen;
int* mArray;
};

#endif

#include "Array.h"

IntArray::IntArray(int len)
{
if (len <= 0)
{
mLen = -1;
return;
}
mArray = new int[len];
mLen = len;
}

IntArray::IntArray(const IntArray& a)
{
if (a.mLen <= 0)
{
return;
}
int len = a.mLen;
mArray = new int[len];
for (int i = 0; i < len; i++)
{
mArray[i] = a.mArray[i];
}
mLen = len;
}

IntArray::~IntArray()
{
mLen = -1;
delete mArray;
}

void IntArray::setData(int index, int value)
{
if (index >= mLen)
{
return;
}

mArray[index] = value;
}

int IntArray::getData(int index) const
{
if (index >= mLen)
{
return -1;
}

return mArray[index];
}

int IntArray::length() const
{
return mLen;
}

IntArray& IntArray::operator=(const IntArray& a)
{
if (mLen > 0)
{
delete[] mArray;
}
if (a.mLen <= 0)
{
return *this;
}
int len = a.mLen;
mArray = new int[len];
for (int i = 0; i < len; i++)
{
mArray[i] = a.mArray[i];
}
mLen = len;
return *this;
}

int& IntArray::operator[](int i)const
{
return mArray[i];
}

bool IntArray::operator==(const IntArray& a)
{
if (mLen != a.mLen)
{
return false;
}
for (int i = 0; i < mLen; i++)
{
if (mArray[i] != a[i])
{
return false;
}
}
return true;
}

bool IntArray::operator!=(const IntArray& a)
{
return !((*this) == a);
}

#include <cstdlib>
#include <iostream>
#include "Array.h"
using namespace std;

void printfIntArray(const IntArray& c)
{

for (int i = 0; i < c.length(); i++)
{
//c[i]
//c.operator[](/*this*/,i);
//cout << c.getData(i) << " ";
cout << c[i] << " ";
}
cout << endl;
}
void main()
{
IntArray a(10);
for (int i = 0; i < a.length(); i++)
{
a[i] = i;
//a.setData(i, i * 2);
}

IntArray b = a;

IntArray c(4);
if (c != a)
{
cout << "不相等" << endl;
}
c = b = a;

printfIntArray(c);
//printfIntArray(a);
//printfIntArray(b);
if (c == a)
{
cout << "相等" << endl;
}
system("pause");
}

10、fwrite fread 的使用,写入数据和读出数据。

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

struct clientData
{
int accNum;
char lastName[15];
char firstName[10];
float balance;
};

int main(int arg, char *args[])
{
int i;
struct clientData cd1;// = {0,"","",0.0};
FILE* cfptr = fopen("credit.dat","w");

if(cfptr == NULL)
{
printf("%s",strerror(errno));
}

for(i = 0; i<2; i++)
{
scanf("%d%s%s%f", &(cd1.accNum), cd1.lastName, cd1.firstName, &(cd1.balance));
fwrite(&cd1,sizeof(struct clientData),1,cfptr);
}

fclose(cfptr);

cfptr = fopen("credit.dat","r");
if(cfptr == NULL)
{
printf("%s",strerror(errno));
}
printf("----start read------\n");
rewind(cfptr);

while(fread(&cd1, sizeof(struct clientData),1,cfptr))
{
printf("%d %s %s %f\n",cd1.accNum, cd1.firstName, cd1.lastName, cd1.balance);
}


return 0;
}

11、不用库函数实现字符串转化为整数和整数转化为字符串

#include <stdio.h>
#include <stdlib.h>

int changeStrToInt(const char* str, int *p)
{
char sy;
if(*str=='\0') return -1;
if(*str =='+' || *str =='-' )
{
sy = *str;
str++;
}

if(*str < '0' || *str > '9') return -1;

int temp = 0;
while(*str != '\0')
{
temp = temp*10 + (*str-'0');
str++;
}

if(sy == '-'){
*p = -temp;
}else{
*p = temp;
}

return 0;
}

int changeIntToStr(const int * num, char *str)
{
char* arr = "0123456789";
int tmp = *num;
if(tmp < 0) tmp = -tmp;
char temp[30]={0};
int i=0;
while(tmp)
{
temp[i] = arr[tmp%10];
tmp = tmp/10;
i++;
}
while(i > 0)
{
*str = temp[i - 1];
str++;
k++;
i--;
}
return 0;
}

int main(int arg, char* args[])
{
int i;
changeStrToInt("123", &i);
printf("%d \n",i);

char b[30]={0};
int k = 123;
changeIntToStr(&k,b);
printf("%s \n",b);
return 0;
}

12、读取1.txt文件(每行是一个整数),将数字从小到大排序,并将排序结果写入2.txt

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>

void sortInt(int *buf, int len)
{
int i = 0 , j = 0;
for(;i < len; i++)
{
for(j = i;j<len; j++)
{
if(buf[i] > buf[j])
{
int temp = buf[i];
buf[i] = buf[j];
buf[j] = temp;
}
}
}
}

int main(int arg, char*args[])
{
if(arg < 2) return -1;
FILE* file = fopen(args[1],"r");
char buf[10] = {0};
int arry[100] = {0};
int len = 0;
while(fgets(buf,sizeof(buf),file))
{
printf("%s",buf);
int temp = atoi(buf);
arry[len] = temp;
len++;
memset(buf,0,sizeof(buf));
}
printf("\n");
sortInt(arry, len);
int i = 0;
for(;i<len;i++)
{
printf("%d ",arry[i]);
}
fclose(file);

FILE* fwr = fopen("b.txt","w");
int j = 0;
while( j < len)
{
memset(buf,0,sizeof(buf));
sprintf(buf,"%d\n",arry[j]);
fputs(buf,fwr);
j++;
}
fclose(fwr);
return 0;
}

13、分析日志,找出每个ip访问服务器的次数,并有序输出。(打印 ip 和其访问的次数)

37.232.193.154 - - [28/May/2015:23:52:39 +0300]
37.232.193.154 - - [28/May/2015:23:52:39 +0300]
194.8.51.253 - - [28/May/2015:23:52:16 +0300]
194.8.51.253 - - [28/May/2015:23:52:16 +0300]
194.8.51.253 - - [28/May/2015:23:52:16 +0300]
46.72.90.124 - - [28/May/2015:23:52:16 +0300]...

#include <fstream>
#include <iostream>
#include <cstdlib>
#include <map>
#include <string>
#include<ctime>

using namespace std;
int main(int argc, char* argv[])
{
ifstream in;
in.open("ios.txt");
string a;
string b;
map<const string, size_t> ipcount;
map<size_t, string> ipsort;
clock_t start, finish;
start = clock();
while (!in.eof())
{
in >> a;
getline(in, b);
++ipcount[a];
}

for (const pair<const string, size_t> &w : ipcount)
{
ipsort[w.second] = w.first;
//cout << w.first << " occrus " << w.second << " times" << endl;
}


for (const pair<size_t, string> &w : ipsort)
{
cout << w.first << " occrus " << w.second << " times" << endl;
}


finish = clock();
cout << finish - start << "/" << CLOCKS_PER_SEC << " (s) " << endl;//500毫秒

system("pause");
return 0;
}

/*int main(int argc, char* argv[])
{
ifstream in;
in.open("ios.txt");
if (!in)
{
return -1;
}
map<const string, size_t> ipcount;

int i = 0;
char c = 0;
char buf[20];
string ip;
clock_t start, finish;
start = clock();
while (!in.eof())
{
memset(buf, 0, 20);
i = 0;
c = 0;
while (1)
{
c = in.get();
if (c != ' ')
{
buf[i++] = c;
}
else
{
break;
}
}

while (in.get() != '\n' && !in.eof())
{

}
ip = buf;
++ipcount[ip];

//cout << ip << endl;
}
finish = clock();
cout << finish - start << "/" << CLOCKS_PER_SEC << " (s) " << endl;// 2秒
for (const pair<const string, size_t> &w : ipcount)
{
cout << w.first << " occrus " << w.second << " times" << endl;
}

system("pause");
return 0;
}*/