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”

相关文章
|
12天前
|
C语言
【c语言】指针就该这么学(1)
本文详细介绍了C语言中的指针概念及其基本操作。首先通过生活中的例子解释了指针的概念,即内存地址。接着,文章逐步讲解了指针变量的定义、取地址操作符`&`、解引用操作符`*`、指针变量的大小以及不同类型的指针变量的意义。此外,还介绍了`const`修饰符在指针中的应用,指针的运算(包括指针加减整数、指针相减和指针的大小比较),以及野指针的概念和如何规避野指针。最后,通过具体的代码示例帮助读者更好地理解和掌握指针的使用方法。
36 0
|
8天前
|
算法 索引
单链表题+数组题(快慢指针和左右指针)
单链表题+数组题(快慢指针和左右指针)
15 1
|
14天前
|
存储 编译器 C语言
【c语言】数组
本文介绍了数组的基本概念及一维和二维数组的创建、初始化、使用方法及其在内存中的存储形式。一维数组通过下标访问元素,支持初始化和动态输入输出。二维数组则通过行和列的下标访问元素,同样支持初始化和动态输入输出。此外,还简要介绍了C99标准中的变长数组,允许在运行时根据变量创建数组,但不能初始化。
31 6
|
11天前
|
C语言
【c语言】指针就该这么学(3)
本文介绍了C语言中的函数指针、typedef关键字及函数指针数组的概念与应用。首先讲解了函数指针的创建与使用,接着通过typedef简化复杂类型定义,最后探讨了函数指针数组及其在转移表中的应用,通过实例展示了如何利用这些特性实现更简洁高效的代码。
11 2
|
11天前
|
C语言
如何避免 C 语言中的野指针问题?
在C语言中,野指针是指向未知内存地址的指针,可能引发程序崩溃或数据损坏。避免野指针的方法包括:初始化指针为NULL、使用完毕后将指针置为NULL、检查指针是否为空以及合理管理动态分配的内存。
|
11天前
|
C语言
C语言:哪些情况下会出现野指针
C语言中,野指针是指指向未知地址的指针,通常由以下情况产生:1) 指针被声明但未初始化;2) 指针指向的内存已被释放或重新分配;3) 指针指向局部变量,而该变量已超出作用域。使用野指针可能导致程序崩溃或不可预测的行为。
|
18天前
|
存储 C语言
C语言32位或64位平台下指针的大小
在32位平台上,C语言中指针的大小通常为4字节;而在64位平台上,指针的大小通常为8字节。这反映了不同平台对内存地址空间的不同处理方式。
|
17天前
|
存储
如何使用指针数组来实现动态二维数组
指针数组可以用来实现动态二维数组。首先,定义一个指向指针的指针变量,并使用 `malloc` 为它分配内存,然后为每个子数组分配内存。通过这种方式,可以灵活地创建和管理不同大小的二维数组。
|
17天前
|
存储
如何通过指针数组来实现二维数组?
介绍了二维数组和指针数组的概念及其区别,详细讲解了如何使用指针数组模拟二维数组,包括定义与分配内存、访问和赋值元素、以及正确释放内存的步骤,适用于需要动态处理二维数据的场景。
|
17天前
|
存储 算法 C语言
C语言:什么是指针数组,它有什么用
指针数组是C语言中一种特殊的数据结构,每个元素都是一个指针。它用于存储多个内存地址,方便对多个变量或数组进行操作,常用于字符串处理、动态内存分配等场景。