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”

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

向着五星的方向

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

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

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

打赏作者

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

抵扣说明:

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

余额充值