先看题目,写一个fun函数,统计一个字符串中某个字符出现的次数,以及这个字符第一次出现的位置。
看起来很简单,似乎几行就可以搞定,但是写出来之后,才发现代码怎么这么长!程序里多处使用了指针,涵盖了下面三种用途:
(1)动态申请内存,返回指针
(2)用指针访问数组中的元素
(3)指针作为函数形参,达到返回多个值的效果
题目面临的两个问题:
(1)输入的字符串长度未知
(2)fun函数需要返回2个值
#include <stdio.h>
#include <stdlib.h>void fun(const char* s, char c, int* count, int* first_pos);int main()
{int size = 10;char* s = (char*)malloc(size); //①动态申请内存if (s == NULL){printf("memory alloc error\n");return -1;}int length = 0;char ch;while ((ch = getchar()) != '\n'){if (length >= size){size *= 2;s = (char*)realloc(s, size);if (s == NULL){printf("memory alloc error\n");return -1;}}*(s + length) = ch; //②访问数组中的元素length++;}*(s + length) = '\0';printf("输入的字符串为:%s\n", s);int count = 0;int pos = -1;char c = 'a';fun(s, c, &count, &pos);printf("字符%c出现了%d次,第一次出现的位置是%d\n", c, count, pos);free(s);return 0;
}void fun(const char* s, char c, int* count, int* first_pos) //③作为函数形参,达到返回多个值的效果
{int cnt = 0;int pos = -1;int i = 0;int found_flag = 0;while (*s != '\0'){if (*s == c){if (found_flag == 0){pos = i;found_flag = 1;}cnt++;}s++;i++;}*count = cnt;*first_pos = pos;
}
以上程序,多处用到了指针,指针的所有操作和内存息息相关。
(1)动态申请内存,返回指针
通过指针p获得对内存的控制权。
(2)用指针访问数组中的元素
数组本身是一个变量,而变量呢,它是内存中的一块区域,所以,通过指针访问数组中的元素,实际上就是通过指针获得了变量所在内存的控制权。由于数组元素在内存中是连续分布的,所以这个指针可以通过++或者--操作访问数组里的元素,这个指针它还描述了“位置信息”。
(3)指针作为函数形参,达到返回多个值的效果
count是一个指针,它指向了原来的实参,通过指针可以直接修改原来的实参,实际上,通过指针获得了实参所在内存的控制权。
c语言的指针,灵活,但是容易出错。
程序追求三个目标“简洁、高效、安全”,c程序的错误,除了逻辑错误之外,最多的就是内存错误,“高效”是c语言的优点,但是安全性……程序员一不小心就是崩溃。
下面用c++改写程序,看不到指针了,程序更加“简洁、安全”。
(1)string是不定长字符串类型,不用动态申请内存了。
(2)有了容器和迭代器,可以不再使用c的指针了。
(3)使用引用代替指针。
#include <iostream>
using namespace std;void fun(const string& s, char c, int& count, int& first_pos);int main()
{string s;cin >> s;cout << "输入的字符串为" << s << endl;int count = 0;int pos = -1;char c = 'a';fun(s, c, count, pos);cout << "字符" << c << "出现了" << count << "次,第一次出现的位置是" << pos << endl;return 0;
}void fun(const string& s, char c, int& count, int& first_pos)
{int cnt = 0;int pos = -1;int i = 0;int found_flag = 0;for (auto elem : s) {if (elem == c){if (found_flag == 0){pos = i;found_flag = 1;}cnt++;}i++;}count = cnt;first_pos = pos;
}