搜索
您的当前位置:首页正文

C语言 #字符指针

来源:爱go旅游网

文章目录


前言

路漫漫其修远兮,武将上下而求索;

以例子为导向来分析字符指针的中存的是什么,以及常量字符串在内存中是如何存储的。


一、指针概念简述

想要详细地了解指针的概念可以戳此链接(详细的万字讲解):

二、字符指针

顾名思义字符指针就是指针变量指向的对象是字符类型,即指针变量的类型为 char*

单个字符的指针创建,代码如下:

#include<stdio.h>

int main()
{
	char ch = 'a';
	char* p = &ch;//此*代表着变量p 为指针变量
	*p = 'b';

	return 0;
}

先来看一下整型的例子: 

int a = 10 ;

int b = a + 2;

"a+2" 是一个表达式的话,那么此表达式就一定有自己的值,然后再将此值赋给b ;

注:表达式有两个属性值属性类型属性

即 "a+2" 的结果为12,那么12就为其值属性;2 为int 类型,变量a 为int 类型,那么 "a+2"此表达式 的类型为int 类型。

eg. char * p = "abcdefg" ;

若将字符串"abcdefg"当作表达式,那么将它赋给指针变量p 的是什么呢?

  • x86环境下,指针变量p 中只能存放大小为4byte 的地址;而显然整个字符串在内存中是连续存放的,即不止占用一个内存单元空间,所以整个字符串会有多个地址;那么指针p是存放不下整个字符串的地址;

我们来看一下打印字符串,代码如下:

#include<stdio.h>

int main()
{
	char ch[10] = "abcdefg";
	char* p = "abcdefg";
	char* p1 = ch; //将数组的首元素地址存放起来

	printf("%s\n", "abcdefg");
	printf("%s\n", ch);
	printf("%s\n", p);
	printf("%s\n", p1);

	printf("字符串地址=%p\n", "abcdefg");
	printf("指针p中存放的地址=%p\n", p);
	printf("指针p1中存放的地址=%p\n", p1);

	return 0;
}

代码运行结果如下:

分析:字符串的创建是用字符数组创建的,我们打印字符串一般采用 printf("%s\n", "abcdefg"); 这种方式,或者将字符串存在数组中,然后对此数组进行打印,即printf("%s\n",ch);

  • 是因为printf函数的占位符%s 只要得到字符串的首字符地址就会一直往后访问直到遇到 '\0' 
  • 还是因为根据的整体字符串"abcdefg"或者整个数组而打印出来整个字符串;
  • 我们知道一个字符在内存中占 1 byte 的空间,而一个内存单元有一个地址,如果是想存放整个字符串的地址,就会存多个地址,但是指针变量在x86环境下只向内存申请了4byte 来存放该地址,所以就无法存放整个字符串的地址;printf("指针p中存放的地址=%p\n", p);的结果看以上代码运行结果,可知p中存放的为一个地址,即字符串首元素的地址

我们将以上的代码又运行了一次:

  • 这是因为 "abcdefg" 是一个常量字符串,即不能被修改的字符串;字符串是存放在内存中的常量区,在编译期间编译器便指派了地址;

注:const 修饰指针变量:(eg. char* p = "abcdefg"; )

1、当 const 放在 * 的左边,有两中写法:

  • 一是 const  char* p = "abcdefg";
  • 二是 char const * p = "abcdefg";

表示 *p 即指针变量p 指向的对象,const 修饰指针p指向的对象也就是说指针p 指向的对象是常变量,即指针p 指向的对象不可被修改

2、当const 放在* 的右边,写作:

  • char* const p = "abcdefg";

字符指针有两种的表示形式:

1、const 不修饰

  • char* p = "abcdefg";

2、const 修饰

  • const char* p = "abcdefg";   
  •  char const * p = "abcdefg";

三、字符在内存中的存储

我们按照例子来分析:

#include<stdio.h>

int main()
{
	const char* p1 = "abcdef";
	const char* p2 = "abcdef";

	char arr1[] = "abcdef";
	char arr2[] = "abcdef";
	if (p1 == p2)
		printf("p1==p2\n");
	else
		printf("p1!=p2\n");

	if (arr1 == arr2)
		printf("arr1==arr2");
	else
		printf("arr1!=arr2");

	return 0;
}

代码运行结果:

分析:常量字符串 ”abcdef“ 存放在内存中的常量区,常量区只能读取而不能对其进行修改;

为什么常量字符串存在常量区?

  • 因为既然常量字符串不能被修改,那么这样的常量就没必要存多份,只要有一份,并且谁都不能去修改它;即常量字符串在内存中存一份便足以够用了;字符串是存放在内存中的常量区,在编译期间编译器便指派了地址;当是一个指针来存放该常量字符串的地址的时候,指针中存放的便是该字符串首元素在常量区中的地址;故而指针p1 与指针 p2 中存放的地址相同,即p1==p2;
  • 而如若是一个数组想要来存放该字符串,编译器便会先将存放在常量区的字符串拷贝放入到此数组之中,数组(假设该数组为局部变量)的空间是在其所在函数的函数栈帧的开辟的时候便确定了;从另外一个角度来看:数组创建时会向内存申请相对的大小空间来存放数组中的数据;而数组arr1 和 数组arr2 都会向内存申请空间来存放其数据,而每个内存单元的编号都不相同,所以就会导致不同空间的地址也不相同;再者,数组名代表着首元素的地址,所以 arr1 ! = arr2 ;

总结

1、字符指针就是指针变量指向的对象是字符类型,即指针变量的类型为 char* ;

3、常量字符串存放在内存中的常量区,常量区中的数据只能读取而不能被修改。

因篇幅问题不能全部显示,请点此查看更多更全内容

Top