C 指针的深造

1 关于内存那点事

2 指针的概念

3 指针变量的定义方法

4 指针的分类

5 指针和变量的关系

6 指针和数组元素之间的关系

7 指针数组

8 指针的指针

9 字符串和指针

9.1 字符串的定义

字符串就是以 \0 结尾的若干的字符的集合。
字符串的地址,是第一个字符的地址。如:字符串 "I Love You !" 的地址,即字符串中字符 'I' 的地址。

  1. 字符串存放在 数组 中;即在内存(栈、静态全局区)中开辟了一段空间存放字符串。
定义了一个字符数组str,用来存放多个字符,并用"I love C!"给 str 数组初始化,
字符串 "I love C!" 存放在 str 中。
char str[100] = "I love C!";

注:
普通全局数组:内存分配在静态全局区
普通局部数组:内存分配在栈区
静态数组(静态全局数组、静态局部数组):内存分配在静态全局区

  1. 字符串存放在 文字常量区;在文字常量区开辟了一段空间存放字符串,将字符串首地址赋值给指针变量。
定义了一个字符指针变量 str,只能存放字符地址编号。
char *str = "I love C !";

"I love C !" 这个字符串中的字符不是存放在 str 指针变量中。
str 只是存放了字符 'I' 的地址编号,"I love C !" 存放在文字常量区。
  1. 字符串存放在 堆区;使用 malloc 等函数在堆区申请空间,将字符串拷贝到堆区。
动态申请了 10 个字节的存储空间,首地址给 str 赋值。
char* str = (char*) malloc(10);

将字符串"I LOVE YOU !"拷贝到 str 指向的内存里。
strcpy(str, "I LOVE YOU !");

9.2 字符串的可修改性:

字符串内容是否可以修改,取决于字符串存放在哪里。

  1. 存放在数组中的字符串的内容可修改
char str[100] = "I love C !";
str[0] = 'x'; //正确可以修改的。
注:数组没有用 const 修饰。
  1. 文字常量区里的内容是不可修改的

char *str = "I love C !";
printf("str = %s\n", str);//"I love C !"
printf("str = %s\n", str+2);//"love C !"

错误!'I' 存放在文字常量区,不可修改。
*str = 'x'; //这么二次赋值 是错误的哦!!!

错误!编译无错,但是赋值结果会导致数据错乱,因为没有正确的结束符!(赋值字符串地址是可以的哦)
char a = 'a';
str = &a;

注:
1、str 指向文字常量区的时候,它指向的内存的内容不可被修改。
2、str 是指针变量可以指向别的地方,即可以给str 重新赋值,让它指向别的地方。

  1. 堆区的内容是可以修改的
char *str = (char*)malloc(10);
strcpy(str, "I love C");
*str = 'y; //正确,可以,因为堆区内容是可修改的

注:
1、str 指向堆区的时候,str 指向的内存内容是可以被修改的。
2、str 是指针变量,也可以指向别的地方。即可以给str 重新赋值,让它指向别的地方

注意:
str 指针指向的内存能不能被修改,要看 str 指向哪里。
str 指向文字常量区的时候,内存里的内容不可修改
str 指向数组(非const 修饰)、堆区的时候,它指向内存的内容是可以修改

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <malloc.h>

int main(int argc, char* argv[])
{
    
    
	char* str = (char*)malloc(sizeof(char)*32);
	if(str){
    
    
		strcpy(str, "I love C");
		strcpy_s(str, 32, "I love C");
	}
	printf("--str = %s--\n", str); //--str = I love C--

	if (str) {
    
    
		*str = 'y'; //正确,可以,因为堆区内容是可修改的
	}
	printf("--str = %s--\n", str); //--str = y love C--
	return 0;
}

9.3 初始化赋值

1.字符数组初始化:

char buf_aver[20] = "hello world";

2.指针指向文字常量区,初始化:

char *buf_point = "hello world";

3、指针指向堆区,堆区存放字符串。
不能初始化,只能先给指针赋值,让指针指向堆区,再使用strcpy、scanf 等方法把字符串拷贝到堆区。

char *buf_heap;
buf_heap = (char *)malloc(15);
strcpy(buf_heap, "hello world");
scanf("%s", buf_heap);

9.4 使用时赋值

  1. 字符数组:使用scanf 或者strcpy
char buf[20] = "hello world";
buf = "hello kitty"; 错误,因为字符数组的名字是个常量,不能用等号给常量赋值。
strcpy(buf, "hello kitty"); 正确,数组中的内容是可以修改的
scanf("%s", buf); 正确,数组中的内容是可以修改的
  1. 指针指向文字常量区
char *buf_point = “hello world”;
1) buf_point = "hello kitty"; 正确,buf_point 指向另一个字符串
2) strcpy(buf_point, "hello kitty"); 错误,这种情况,buf_point 指向的是文字常量区,内容只读。

当指针指向文字常量区的时候,不能通过指针修改文字常量区的内容。

  1. 指针指向堆区,堆区存放字符串
char *buf_heap;
buf_heap = (char *)malloc(15);
strcpy(buf_heap, "hello world");
scanf("%s", buf_heap);

9.5 字符串和指针总结

1、指针可以指向 文字常量区
1)指针指向的文字常量区的内容不可以修改
2)指针的指向可以改变,即可以给指针变量重新赋值,指针变量指向别的地方。

2、指针可以指向 堆区
1)指针指向的堆区的内容可以修改。
2)指针的指向可以改变,即可以给指针变量重新赋值,指针变量指向别的地方。

3、指针也可以指向 数组(非const 修饰)
char buf[20] = "hello world";
char *str = buf;
这种情况下
1)可以修改buf 数组的内容。
2)可以通过str 修改str 指向的内存的内容,即数组buf 的内容。
3)不能给buf 赋值 buf = “hello kitty”; 错误的。
4)可以给str 赋值,及str 指向别处。str = “hello kitty”;

10 数组指针

11 指针和函数的关系

12 经常容易混淆的指针概念

13 特殊指针

猜你喜欢

转载自blog.csdn.net/Michael_lcf/article/details/129094236