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”

相关文章
|
16天前
|
存储 C语言
【C语言基础】一篇文章搞懂指针的基本使用
本文介绍了指针的概念及其在编程中的应用。指针本质上是内存地址,通过指针变量存储并间接访问内存中的值。定义指针变量的基本格式为 `基类型 *指针变量名`。取地址操作符`&`用于获取变量地址,取值操作符`*`用于获取地址对应的数据。指针的应用场景包括传递变量地址以实现在函数间修改值,以及通过对指针进行偏移来访问数组元素等。此外,还介绍了如何使用`malloc`动态申请堆内存,并需手动释放。
|
16天前
|
存储 编译器 C语言
【C语言基础考研向】09 一维数组
数组是一种有序集合,用于存储相同类型的数据,便于统一操作与管理。例如,将衣柜底层划分为10个格子存放鞋子,便于快速定位。在C语言中,数组定义格式为 `类型说明符数组名[常量表达式];`,如 `int a[10];` 表示定义了一个包含10个整数的数组。数组初始化时可以直接赋值,也可以部分赋值,且数组长度必须固定。数组在内存中连续存储,访问时需注意下标范围,避免越界导致数据异常。数组作为参数传递时,传递的是首地址,修改会影响原数组。
|
16天前
|
存储 C语言
【C语言基础考研向】10 字符数组初始化及传递和scanf 读取字符串
本文介绍了C语言中字符数组的初始化方法及其在函数间传递的注意事项。字符数组初始化有两种方式:逐个字符赋值或整体初始化字符串。实际工作中常用后者,如`char c[10]=&quot;hello&quot;`。示例代码展示了如何初始化及传递字符数组,并解释了为何未正确添加结束符`\0`会导致乱码。此外,还讨论了`scanf`函数读取字符串时忽略空格和回车的特点。
|
16天前
|
存储 Serverless C语言
【C语言基础考研向】11 gets函数与puts函数及str系列字符串操作函数
本文介绍了C语言中的`gets`和`puts`函数,`gets`用于从标准输入读取字符串直至换行符,并自动添加字符串结束标志`\0`。`puts`则用于向标准输出打印字符串并自动换行。此外,文章还详细讲解了`str`系列字符串操作函数,包括统计字符串长度的`strlen`、复制字符串的`strcpy`、比较字符串的`strcmp`以及拼接字符串的`strcat`。通过示例代码展示了这些函数的具体应用及注意事项。
|
19天前
|
存储 人工智能 C语言
C语言程序设计核心详解 第八章 指针超详细讲解_指针变量_二维数组指针_指向字符串指针
本文详细讲解了C语言中的指针,包括指针变量的定义与引用、指向数组及字符串的指针变量等。首先介绍了指针变量的基本概念和定义格式,随后通过多个示例展示了如何使用指针变量来操作普通变量、数组和字符串。文章还深入探讨了指向函数的指针变量以及指针数组的概念,并解释了空指针的意义和使用场景。通过丰富的代码示例和图形化展示,帮助读者更好地理解和掌握C语言中的指针知识。
|
19天前
|
存储 人工智能 C语言
C语言程序设计核心详解 第六章 数组_一维数组_二维数组_字符数组详解
本章介绍了C语言中的数组概念及应用。数组是一种存储同一类型数据的线性结构,通过下标访问元素。一维数组定义需指定长度,如`int a[10]`,并遵循命名规则。数组元素初始化可使用 `{}`,多余初值补0,少则随机。二维数组扩展了维度,定义形式为`int a[3][4]`,按行优先顺序存储。字符数组用于存储字符串,初始化时需添加结束符`\0`。此外,介绍了字符串处理函数,如`strcat()`、`strcpy()`、`strcmp()` 和 `strlen()`,用于拼接、复制、比较和计算字符串长度。
|
24天前
|
C语言
C语言 字符串操作函数
本文档详细介绍了多个常用的字符串操作函数,包括 `strlen`、`strcpy`、`strncpy`、`strcat`、`strncat`、`strcmp`、`strncpy`、`sprintf`、`itoa`、`strchr`、`strspn`、`strcspn`、`strstr` 和 `strtok`。每个函数均提供了语法说明、参数解释、返回值描述及示例代码。此外,还给出了部分函数的自实现版本,帮助读者深入理解其工作原理。通过这些函数,可以轻松地进行字符串长度计算、复制、连接、比较等操作。
|
24天前
|
存储 安全 C语言
C语言 二级指针应用场景
本文介绍了二级指针在 C 语言中的应用,
|
1月前
|
搜索推荐 C语言
指针与数组
指针与数组
50 9
|
1月前
|
存储 编译器 数据处理
【编程秘籍】解锁C语言数组的奥秘:从零开始,深入浅出,带你领略数组的魅力与实战技巧!
【8月更文挑战第22天】数组是C语言中存储同类型元素的基本结构。本文从定义出发,详述数组声明、初始化与访问。示例展示如何声明如`int numbers[5];`的数组,并通过下标访问元素。初始化可在声明时进行,如`int numbers[] = {1,2,3,4,5};`,编译器自动计算大小。初始化时未指定的元素默认为0。通过循环可遍历数组,数组名视为指向首元素的指针,方便传递给函数。多维数组表示矩阵,如`int matrix[3][4];`。动态数组利用`malloc()`分配内存,需用`free()`释放以避免内存泄漏。掌握这些技巧是高效数据处理的基础。
55 2