C语言指针的几种用途

先看题目,写一个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;
}

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值