C语言指针总结提高(指针操作字符串)

字符串在C中是比较特殊的一类数据类型,学习时候总感觉和其他数据类型有区别。然后最近在看视频和查资料的时候总结一下。

1.字符串定义

之前对字符串初始化都是似懂非懂的,这里做个总结。

1.1字符串初始化

  • C中字符串 是以0结尾的字符串
  • C中没有字符串类型,可以通过字符数组来模拟字符串。也就是说只有char,没有string。
int main(void)
{
	char p1[] = { 'c','u','o' };
	char p2[] = { 'w','e','t','\0' };
	char p3[] = "hello";
	char p = '3';

	printf("%c\n", p);
	printf("%s\n", p2);
	printf("%s\n", p3);
	printf("hello\n");
	system("pause");
}

上面列出是比较常见的几种声明方式。

  1. 首先,p1这种方法都编译通过,但是不能打印出来,就算打印了也是不正确的字符。必须后面加个’\0’。
  2. 最最常见是p3声明方式。
  3. 还有就是字符串只有一个可见字符时只能单引号,而且输出用%c,而不是%s

1.2字符串和字符数组

char p[] = "hello";
char *p1 = "hello";

这两个都是指向同个字符串。
但是 p是字符数组 --------------p1是指针。
还有一点要注意,p1是常量指针,不能被修改。
也就是说不能执行以下操作:

char p[] = "hello";
p = p + 1;

编译器会报错,因为在释放指针内存时,要保证完整。
发现一篇博客写的很好:字符串
这位大哥总结的很完整。

1.3strlen()和sizeof()

#include "stdio.h"

int main(void)
{
	char a[] = "abcd";
	printf("%5d", strlen(a));
	printf("%5d", sizeof(a));

	system("pause");
	return 0;
}

在这里插入图片描述
这里我们可以看到:

  • strlen()长度不包括0
  • sizeof()是内存的大小,包括0

2.字符串基本操作

2.1字符串遍历

字符串遍历有三种方式,其本质其实是一样的。

#include "stdio.h"

int main(void)
{
	char a[] = "asdsfjklg";
	char *p = NULL;
	int i = 0;
	p = a;
	for (i = 0; i < strlen(a);i++)
	{
		printf("%5c", a[i]);
	}

	for (i = 0; i < strlen(a); i++)
	{
		printf("%5c", *(p + i));
	}

	for (i = 0; i < strlen(a); i++)
	{
		printf("%5c", *(a + i));
	}
	printf("\n");
	printf("hello\n");
	system("pause");
	return 0;
}

第一种是我们最常见的遍历,但是第二种才是编译器的理解,所以按照第二种写效率会更高。
从这个例子可以知道其实 *和[]是一样的,只是表现形式不一样。

2.2字符串的拷贝(包括传参)

#include "stdio.h"

int main(void)
{
	char a[] = "hsdkjfj";
	char b[123];
	int i = 0;
	for (; *(a + i) != '\0'; i++)
	{
		*(b + i) = *(a + i);
	}

	b[i] = '\0';

	printf("%s\n", b);
	printf("hello\n");
	system("pause");
	return 0;
}

这是不传参的,要注意for里面的判断条件,当然也可以写a[i] !=’\0’。
还有不要忘了在最后加个\0,不然会出错。

#include "stdio.h"

int StrCopy(char *a, char *b)
{
	char *from = NULL;
	char *to = NULL;
	from = a;
	to = b;
	if (from == NULL || to == NULL )
	{
		return;
	}
	int i = 0;
	for (; *(a + i) != '\0';)
	{
		*(b++) = *(a++);
	}
	*(b + i) = '\0';
	return 0;
}

int StrCopy1(char *a, char *b)
{
	char *from = NULL;
	char *to = NULL;
	from = a;
	to = b;
	if (from == NULL || to == NULL)
	{
		return;
	}
	int i = 0;
	while ((*to = *from) != '\0')
	{
		to++;
		from++;
	}

	return 0;
}

int StrCopy2(char *a, char *b)
{
	char *from = NULL;
	char *to = NULL;
	from = a;
	to = b;
	if (from == NULL || to == NULL  )
	{
		return;
	}
	int i = 0;
	while((*to ++ = *from++) != '\0')
	{
		;
	}
	
	return 0;
}

int main(void)
{
	char *a = "nidwqej";
	char b[100];
	int ret = 0;
	
	ret = StrCopy2(a, b);
	
	if (ret != 0)
	{
		printf("ERROR\n");
	}
	printf("%s\n", b);
	
	printf("hello\n");
	system("pause");
	return 0;
}

上面有三种不同拷贝方法,都需要学习,对提高代码编写能力有提高。

2.3要注意的问题

刚刚上面代码最好每个形参过来,在每个被调函数里面再申明变量把形参接过来,尽量不要去改变形参的值。
比如:

int StrCopy1(char *a, char *b)
{
	int i = 0;
	while ((*b= *a) != '\0')
	{
		b++;
		a++;
	}
	printf("%s",a);
	return 0;
}

这样会出问题的,因为a的指向一直在变,到最后是不能得到相应结果的。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值