C语言指针(四)

字符串的引用方式

  • 用字符数组存放一个字符串,可以通过数组名和小标引用字符串中的一个字符,也可以通过数组名和格式声明“%s”输出该字符串
    比如
char string[]="I Love China";
printf("%s\n",string)

其中字符串数组名string是指针变量,指向内存给字符串开辟地址的首地址。内存中,字符串的最后自动加了一个‘\0’。在输出项中给出字符指针名string,则系统会输出string所指向的字符串第一个字符,然后自动使指针变量string加1,使之指向下一个字符,直到遇见字符串结束标志‘\0’为止。但是对于数值型数组,只能一个个输出

  • 字符指针变量指向一个字符串常量,通过字符串指针变量引用字符串常量。
    比如
char *string="I love China!";
//char *string;
//string="I love China";
print("%s\n",string);

数组没有名字,字符指针变量string指向不知名数组的首元素地址。C语言对字符串常量是按字符数组处理的,在内存中开辟了一个字符数组来存放字符串常量,但是这个字符数组是没有名字的。因此不能用数组名来引用,只能通过指针变量来引用。这时的string是指针变量,不能对string进行在赋值,一旦进行在复制,那他代表的地址就是新字符串的首地址了,如下:

int *string=“I love china”;
string="you are beautiful";

上边的例子指针变量string已经指向了新字符串

	int a[2] = { 1,2 };
	int* p;
	p = a;
	printf("%d", *p);

上面的代码就是把数组a的首地址赋给了指针变量p,以此类推string="I love China"就是把字符串数组首元素地址赋给了指针变量string。只不过表达形式不一样,人家没有名字,只能这样。就比如有一个班级40个人拍成一列,如果有班级名字我就说莫某班不错,但是如果没有班级的名字,我就只能说这一列学生不错。

对字符串中字符的存取

可以使用下标的方法,也可以使用指针的版办法。

实例1

字符串a复制为字符串b
#include<stdio.h>
int main()
{
	char a[] = "I am a student.", b[20];
	int i;
	for (i = 0; *(a + i) != '\0'; i++)
	{
		*(b + i) = *(a + i);
	}
	*(b + i) = '\0';
	printf("string a is:%s\n", a);
	printf("string b is:");
	for (i = 0; b[i] != '\0'; i++)
	{
		printf("%c", b[i]);
	}
	printf("\n");

	return 0;
}

实例2

上边的例子
#include<stdio.h>
int main()
{
	char a[] = "I am a student.", b[20];
	char * p1, * p2;
	p1 = a;
	p2 = b;
	for (; *p1 != '\0'; p1++, p2++);
	{
		*p2 = *p1;
	}
	*p2 = '\0';
	printf("string a is:%s\n", a);
	printf("string b is:%s\n", b);
	return 0;
}

字符指针做函数参数

用字符数组名作为函数参数

int main()
{
	void copy_string(char from[], char to[]);
	char a[] = "I am a teacher";
	char b[] = "you are a student";
	copy_string(a, b);
	printf("a:%s", a);
	printf("b:%s", b);
}
void copy_string(char *from, char to[])
{
	int i = 0;
	while (from[i] != '\0')
	{
		*(to+i) = from[i]; i++;
	}
	to[i] = '\0';
}

用字符型指针变量做实参

int main()
{
	void copy_string(char from[], char to[]);
	char a[] = "I am a teacher";
	char b[] = "you are a student";
	char *from=a,*to=b;
	copy_string(from, to);
	printf("a:%s", a);
	printf("b:%s", b);
}
void copy_string(char from[], char to[])
{
	int i = 0;
	while (from[i] != '\0')
	{
		*(to+i) = from[i]; i++;
	}
	to[i] = '\0';
}

用字符指针变量作形参和实参

int main()
{
	void copy_string(char *from, char *to);
	char *a = "I am a teacher";
	char b[] = "you are a student";
	char *p=b;
	copy_string(a, p);
	printf("a:%s", a);
	printf("b:%s", b);
}
void copy_string(char *from, char *to)
{
	int i = 0;
	while (from[i] != '\0')
	{
		*(to+i) = from[i]; i++;
	}
	to[i] = '\0';
}

使用字符指针变量和字符数组的比较

	int a[3] = { 1,2,3 };
	int* p;
//	p = a;
	printf("please  input a num:");
	scanf_s("%d\n", p);
	for (int i = 0; i < 3; i++)
	{
		printf("%d", *(a + i));
	}

错误C4700	使用了未初始化的局部变量“p”	

在编译的时候还给指针变量a分配了储存单元,变量a的地址是已经指定的,但是a并未被赋值,在a的储存单元中是一个不可预料的值,在执行scanf的时候,要求将一个数输入到a所指向的一段储存单元,但是因为我们根本不知道a现在指向那里,所以很危险。如果a现在指向一个空白的出储存单元的话还好,如果a指向了已经存放指令或者数据的有用内存段,就会破坏程序或者有用数据,甚至破坏系统。vs编译中为了避免出现这种破坏系统的危险行为,就在底层这样设置了,指针变量不初始化赋值就无法进行写数据。

  • 编译的时候,字符数组分配若干的储存单元,以存放各元素的值。而对字符指针变量,只分配一个储存单元(用来储存数组某元素的地址)
  • 指针变量的值是可以改变的,而字符数组名代表一个固定的值(数组首元素的地址),不能改变
char *a=”I love you“;
a=a+7
这是可行的,只是指针变量值发生变化,改变了指向

char a[]={"I love you"}
a=a+7
这种写法是错误的
  • 字符数组各个元素是可以改变的,但是字符指针常量指向的字符串常量种的内容是不能改变的

-可以对字符指针变量进行赋值,不能对数组名进行赋值

关于区别参考P262

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

星光技术人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值