C语言-指针进阶(1.字符指针)

162 阅读3分钟

前言:指针的基础知识

  1. 指针就是个变量,用来存放地址,地址唯一标识一块内存空间。
  2. 指针的大小是固定的4/8个字节(32位平台/64位平台)。
  3. 指针是有类型,指针的类型决定了指针的+-整数的步长,指针解引用操作的时候的权限。
  4. 指针的运算。

本篇先了解最简单的指针字符指针,后面还有指针数组、数组指针、数组参数和指针参数、函数指针、函数指针数组、指向函数指针数组的指针、回调函数。

字符指针

定义方式:char*、const char*

使用方式如下:

    char ch = 'w';
    char *pc = &ch;
    *pc = 'w';

    const char* pstr = "hello world";
    printf("%s\n", pstr);

注意:上面的第五行代码是把一个字符串放到pstr指针变量里了吗?初学者可能会认为是的,但其实并不是,本质上是把字符串hello world的首字符的地址存放到pstr中。使用const关键字修饰char* 代表的是pstr所指向的内容不能改变,就是不能使用pstr=“test”改变内容。const char * p 和char * const p具有不同的意义,前者是p不可修改,后者是p不可修改。

	//字符指针是一个变量,用于存放字符串的首地址。
	char* ps = "dad";//本质上是把字符串的首字符的地址存储在指针中
	char arr[] = "aaa aa";
	//字符串中每个字符都有一个内存地址,而字符串的首字符地址就代表了整个字符串的位置。
	printf("%s\n", ps);//%s打印字符:给出首字符地址,就可以打印整个字符串。
	printf("%s\n", arr);
	printf("%c\n", *ps);

使用字符指针指向字符串和使用字符数组存放字符串有什么区别呢?那么请看下面的代码,并尝试给出答案

  char str1[] = "hello C";//数组先开辟一块空间,再存放内容
  char str2[] = "hello C";
  const char* str3 = "hello C";
	//*str3 = 'w';//常量字符串的内容不能改变
	char* str4 = "hello C";
	//*str4 = 'w';
	if (str1 == str2)
	{
		printf("1=2");
	}
	if (str3 == str4)
	{
		printf("3=4");
	}

答案是3==4。字符数组是开辟一块新空间,然后存放内容,数组名就是新空间的首地址;而字符指针存放字符串的首地址,对于同一个常量字符串,在代码段(常量区)里存放的地址是一样的,指向同一个常量字符串的时候,str3和str4实际上指向同一块内存,所以str3==str4,而str1!=str2.

ps:补充一个小知识,有助于后面的理解: []表示指针运算符,用来计算指针加上或减去一个整数后所指向的地址。例如,p[0]等价于p,p[1]等价于(p+1),指针加一的步长是根据指针的类型确定的,如char* pc,pc+1就是地址加一,因为char是一个字节大小;int* pi,pi+1就是地址加4,因为int是4个字节大小。

int main()
{
	int a[5] = { 1,2,3,4,5 };
	int b[] = { 0,1,2,3,4,5 };
	int c[] = { 3,44,5,6,7 };
	int* arr[3] = { a,b,c };//指针数组
	int i = 0;
	for (i = 0; i < 3; i++)
	{
		int j = 0;
		for (j = 0; j < 5; j++)
		{
			//printf("%d ", *(arr[i] + j));
			printf("%d ", arr[i][j]);// []表示指针运算符,用来计算指针加上或减去一个整数后所指向的地址。例如,p[0]等价于*p,p[1]等价于*(p+1)
		}
		printf("\n");
	}
	return 0;
}

字符指针就介绍到这里,后面会介绍数组指针。