C语言之指针(指针数组以及指针的指针和字符串)

简介: C语言之指针(指针数组以及指针的指针和字符串)

5.1.7 指针数组

1、指针和数组的关系

1:指针可以保存数组元素的地址

2:可以定义一个数组,数组中有若干个相同类型指针变量,这个数组被称为指针数组 int *p[5]

指针数组的概念:

指针数组本身是个数组,是个指针数组,是若干个相同类型的指针变量构成的集合

2、指针数组的定义方法:

类型说明符 * 数组名 [元素个数];

int * p[5];//定义了一个整型的指针数组 p,有 5 个元素 p[0]~p[4],

每个元素都是 int *类型的变量

int a;

p[0]=&a;

int b[10];

p[1]=&b[5];

p[2]、*(p+2)是等价的,都是指针数组中的第 2 个元素

例 13:
#include <stdio.h>
int main(int argc, char *argv[])
{
char *name[5] = {"hello","China","beijing","project","Computer"};
int i;
for(i=0;i<5;i++)
{
printf("%s\n",name[i]);
}
return 0;
}


“hello”、“China”“beijing” “project” “computer” 这 5 个字符串存放在文字常量区。

假设:

“hello ”首地址是 0x00002000

“China”首地址是 0x00003000

“beijing”首地址是 0x00004000

“project”首地址是 0x00005000

“Computer”首地址是 0x00006000

则: name[0]中存放内容为 0x00002000

name[1]中存放内容为 0x00003000

name[2]中存放内容为 0x00004000

name[3]中存放内容为 0x00005000

name[4]中存放内容为 0x0000600

注意:name[0] name[1] name[2] name[3] name[4] 分别是 char * 类型的指针变量,分别存放一个地址编号。

3、指针数组的分类

字符指针数组 char *p[10]、短整型指针数组、整型的指针数组、长整型的指针数组

float 型的指针数组、double 型的指针数组 结构体指针数组、函数指针数组

5.1.8 指针的指针

指针的指针,即指针的地址,

咱们定义一个指针变量本身指针变量占 4 个字节,指针变量也有地址编号。

例: int a=0x12345678;

假如:a 的地址是 0x00002000 int *p; p =&a;

则 p 中存放的是 a 的地址编号即 0x00002000 因为 p 也占 4 个自己内存,也有它自己的地址编号,及指针变量的地址,即指针的指针。

假如:指针变量 p 的地址编号是 0x00003000,这个地址编号就是指针的地址 我们定义一个变量存放 p 的地址编号,这个变量就是指针的指针

int **q;

q=&p;//q 保存了 p 的地址,也可以说 q 指向了 p

则 q 里存放的就是 0x00003000

int ***m;

m=&q;

p q m 都是指针变量,都占 4 个字节,都存放地址编号,只不过类型不一样而已

5.1.9 字符串和指针

字符串的概念: 字符串就是以’\0’结尾的若干的字符的集合:比如“helloworld”。

字符串的地址,是第一个字符的地址。

如:字符串“helloworld”的地址,其实是字符串中字符’h’的地址。

我们可以定义一个字符指针变量保存字符串的地址,

比如:char *s =”helloworld”;

字符串的存储形式:

数组、文字常量区、堆

1、 字符串存放在数组中 其实就是在内存(栈、静态全局区)中开辟了一段空间存放字符串。 char string[100] = “I love C!”

定义了一个字符数组 string,用来存放多个字符,并且用”I love C!”给 string 数组初始化 ,字符串“I love C!”存放在 string 中。

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

2、 字符串存放在文字常量区 在文字常量区开辟了一段空间存放字符串,将字符串的首地址付给指针变量。

char *str = “I love C!”

定义了一个指针变量 str,只能存放字符地址编号, I love C! 这个字符串中的字符不是存放在 str 指针变量中。 str 只是存放了字符 I 的地址编号,“I love C!”存放在文字常量区

3、 字符串存放在堆区 使用 malloc 等函数在堆区申请空间,将字符串拷贝到堆区。

char *str =(char*)malloc(10);//动态申请了 10 个字节的存储空间,

首地址给 str 赋值。

strcpy(str,"I love C");//将字符串“Ilove C!”拷贝到 str 指向的内存里

字符串的可修改性:

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

1. 存放在数组中的字符串的内容是可修改的

char str[100]=”I love C!”;

str[0]=‘y’;//正确可以修改的

注:数组没有用 const 修饰

2. 文字常量区里的内容是不可修改的

char *str=”I love C!”; *str =’y’;//错误,I 存放在文字常量区,不可修改

注: 1、str 指向文字常量区的时候,它指向的内存的内容不可被修改。

2、str 是指针变量可以指向别的地方,即可以给 str 重新赋值,让它指向别的地方。

3. 堆区的内容是可以修改的 char *str =(char*)malloc(10);

strcpy(str,"I love C");

*str=’y’;//正确,可以,因为堆区内容是可修改的

注: 1、str 指向堆区的时候,str 指向的内存内容是可以被修改的。

2、str 是指针变量,也可以指向别的地方。即可以给 str 重新赋值,让它指向别的地方

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

初始化:

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);

使用时赋值

1. 字符数组:使用 scanf或者 strcpy

char buf[20]=”hello world” buf="hello kitty"; 错误,因为字符数组的名字是个常量,不能用等号给常量赋值。

strcpy(buf,"hello kitty"); 正确,数组中的内容是可以修改的

scanf("%s",buf); 正确,数组中的内容是可以修改的

2. 指针指向文字常量区

char *buf_point = “hello world”;

(1) buf_point="hello kitty"; 正确,buf_point 指向另一个字符串

(2) strcpy(buf_point,"hello kitty"); 错误,这种情况,buf_point 指向的是文字常量区,内容只读。 当指针指向文字常量区的时候,不能通过指针修改文字常量区的内容。

3.指针指向堆区,堆区存放字符串

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

字符串和指针总结:

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”

相关文章
|
2月前
|
存储 NoSQL 编译器
【C语言】指针的神秘探险:从入门到精通的奇幻之旅 !
指针是一个变量,它存储另一个变量的内存地址。换句话说,指针“指向”存储在内存中的某个数据。
124 3
【C语言】指针的神秘探险:从入门到精通的奇幻之旅 !
|
2月前
|
存储 C语言 开发者
【C语言】字符串操作函数详解
这些字符串操作函数在C语言中提供了强大的功能,帮助开发者有效地处理字符串数据。通过对每个函数的详细讲解、示例代码和表格说明,可以更好地理解如何使用这些函数进行各种字符串操作。如果在实际编程中遇到特定的字符串处理需求,可以参考这些函数和示例,灵活运用。
92 10
|
2月前
|
存储 编译器 C语言
【C语言】指针大小知多少 ?一场探寻C语言深处的冒险 !
在C语言中,指针的大小(即指针变量占用的内存大小)是由计算机的体系结构(例如32位还是64位)和编译器决定的。
179 9
|
2月前
|
安全 程序员 C语言
【C语言】指针的爱恨纠葛:常量指针vs指向常量的指针
在C语言中,“常量指针”和“指向常量的指针”是两个重要的指针概念。它们在控制指针的行为和数据的可修改性方面发挥着关键作用。理解这两个概念有助于编写更安全、有效的代码。本文将深入探讨这两个概念,包括定义、语法、实际应用、复杂示例、最佳实践以及常见问题。
64 7
|
2月前
|
传感器 算法 安全
【C语言】两个数组比较详解
比较两个数组在C语言中有多种实现方法,选择合适的方法取决于具体的应用场景和性能要求。从逐元素比较到使用`memcmp`函数,再到指针优化,每种方法都有其优点和适用范围。在嵌入式系统中,考虑性能和资源限制尤为重要。通过合理选择和优化,可以有效提高程序的运行效率和可靠性。
186 6
|
3月前
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
99 5
|
3月前
|
存储 算法 C语言
C语言中常见的字符串处理技巧,包括字符串的定义、初始化、输入输出、长度计算、比较、查找与替换、拼接、截取、转换、遍历及注意事项
本文深入探讨了C语言中常见的字符串处理技巧,包括字符串的定义、初始化、输入输出、长度计算、比较、查找与替换、拼接、截取、转换、遍历及注意事项,并通过案例分析展示了实际应用,旨在帮助读者提高编程效率和代码质量。
182 4
|
3月前
|
存储 程序员 编译器
C 语言数组与指针的深度剖析与应用
在C语言中,数组与指针是核心概念,二者既独立又紧密相连。数组是在连续内存中存储相同类型数据的结构,而指针则存储内存地址,二者结合可在数据处理、函数传参等方面发挥巨大作用。掌握它们的特性和关系,对于优化程序性能、灵活处理数据结构至关重要。
|
3月前
|
算法 C语言
C语言中的文件操作技巧,涵盖文件的打开与关闭、读取与写入、文件指针移动及注意事项
本文深入讲解了C语言中的文件操作技巧,涵盖文件的打开与关闭、读取与写入、文件指针移动及注意事项,通过实例演示了文件操作的基本流程,帮助读者掌握这一重要技能,提升程序开发能力。
216 3
|
3月前
|
存储 算法 程序员
C 语言指针详解 —— 内存操控的魔法棒
《C 语言指针详解》深入浅出地讲解了指针的概念、使用方法及其在内存操作中的重要作用,被誉为程序员手中的“内存操控魔法棒”。本书适合C语言初学者及希望深化理解指针机制的开发者阅读。

热门文章

最新文章