Logo

郎哥编程

指针数组和数组指针

2024-05-14 23

指针数组

指针数组是一个数组,是指由指针构成的数组,在这个数组中的所有元素都是指针,每个指针占用相同的字节。

我们知道整型数组是用来存储整型数据的数组:

int arr[5]={11,20,32,62,0};

数组arr有5个元素,每个元素都是整型数据。

指针数组就是用来存储指针的数组,声明指针数组需要在数据类型的后面添加“*”符号,表示这是一个指针数组。

例如:

int*  a[6]; 

 //定义了一个整型指针数组,名称为a,数组中的元素类型是指向整型数据的指针,数组大小为6个元素。

float*   score[3+3];

//定义了一个浮点数组,名称为score,数组中的元素类型是指向浮点数据的指针,数组大小为5个元素。

例1:指针数组的使用

案例定义了一个指针数组,每个指针都指向一个整数。然后遍历这个指针数组并打印出所有整数。

程序清单

#include <stdio.h>
int main() {
    // 声明一个指针数组,每个元素都是一个字符串指针
    char *array[] = {
        37,
        12,
        0,
        101,
        19
    };
    // 获取数组的长度
    int length = sizeof(array) / sizeof(array[0]);
    // 遍历数组并打印每个整数
    for (int i = 0; i < length; i++) {
        printf("%d\n", array[i]);
    }
    return 0;
}

案例代码首先定义了一个包含5个整数的指针数组。然后,通过计算sizeof(array) / sizeof(array[0])获取数组的长度。接着,使用一个for循环遍历数组,并使用printf函数打印每个整数。

例2:猜数游戏

案例使用指针数组创建一个猜数字的小游戏。游戏会随机生成一个1到100之间的数字,然后让用户尝试猜测这个数字。用户每次输入猜测的数字后,程序会告诉用户猜测的数字比生成的数字是高、低、还是正确。

程序清单

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
// 函数声明
void playGame();
int generateRandomNumber();
void getUserGuess(int *guess);
void checkGuess(int number, int guess);
int main() {
    // 开始游戏
    playGame();
    return 0;
}
// 游戏主循环
void playGame() {
    int randomNumber = generateRandomNumber();
    int guess;
    int attempts = 0;
    printf("欢迎来到猜数字游戏!\n");
    printf("我已经想好了一个1到100之间的数字。\n");
    do {
        getUserGuess(&guess);
        attempts++;
        checkGuess(randomNumber, guess);
    } while (guess != randomNumber);
    printf("恭喜你,你猜对了!数字是 %d。\n", randomNumber);
    printf("你总共尝试了 %d 次。\n", attempts);
}
// 生成1到100之间的随机数字
int generateRandomNumber() {
    srand(time(NULL)); // 使用当前时间作为随机数种子
    return rand() % 100 + 1;
}
// 获取用户的猜测并将其存储在指针所指向的位置
void getUserGuess(int *guess) {
    printf("请输入你的猜测:");
    scanf("%d", guess);
    while (*guess < 1 || *guess > 100) {
        printf("输入无效,请重新输入一个1到100之间的数字:");
        scanf("%d", guess);
    }
}
// 检查用户的猜测并给出相应的反馈
void checkGuess(int number, int guess) {
    if (guess < number) {
        printf("太低了!再试一次。\n");
    } else if (guess > number) {
        printf("太高了!再试一次。\n");
    }
}

案例输出:

欢迎来到猜数字游戏!

我已经想好了一个1到100之间的数字。

请输入你的猜测:50

太低了!再试一次。

请输入你的猜测:75

太高了!再试一次。

请输入你的猜测:62

太低了!再试一次。

请输入你的猜测:68

恭喜你,你猜对了!数字是 68。

你总共尝试了 4 次。

注意:每次运行程序时,由于generateRandomNumber函数使用当前时间作为随机数种子,因此生成的随机数字都会不同。此外,为了确保程序的健壮性,getUserGuess函数会检查用户的输入是否在有效范围内,如果不是,则要求用户重新输入。

数组指针

指针变量也可以指向数组元素的内存地址,可以利用指针来访问数组的元素。当声明一个数组变量后,C编译器会为该数组分配连续的存储空间,用于存储数组内的元素,每个元素占用的空间为该元素所属数据类型的空间大小。

一个指针变量可以指向一个数组,也可以指向一个数组元素。将一个数组的地址赋值给指针变量可以写为:

p = a;

该语句将数组a的首地址赋值给指针变量p。当把一个数组元素的首地址,一般是数组第一个元素的地址赋值给指针变量时,该指针变量是指向了数组第1个元素的内存地址,然后应用指针的加减运算就可以访问数组的全部元素。

上图描述了指针与数组元素内存地址的关系。array为具有三个短整型元素的数组,p为短整型的指针,p=array将数组array首地址赋值给p,此时指针变量p指向数组array的第1个元素,p+1指向第2个元素,p+2指向第3个元素。

一个指针变量既可以指向一个数组,也可以指向一个数组元素。如果要使指针指向数组的第一个元素,可以把数组名或第一个数组元素的地址赋值给该指针变量。如果需要该指针指向第i个元素的地址,可以把第i个元素的内存地址或数组名加i赋值给该指针。

int data[]={11,21,23};
int *p;
// 数组data第2个元素地址赋值给p
p = data+1;
// 或者
p = &data[1];

上面的代码将data数组的第2个元素的内存地址赋值给指针变量p。当指针变量p指向了数组元素或数组首地址后,就可以通过指针变量的自增或自减来访问数组的各个元素。

例3:遍历数组的元素

程序清单 sample.c

#include<stdio.h>
void main()
{
	// 声明数组data
	int data[]={11,21,23,8,9,100};
	// 声明执行int类型的指针变量
	int *p,i;
	// 数组首地址赋值给data
	p = data;
	// 输出数组全部元素
	for(i=0;i<6;i++)
	{
		printf(第%d个数组元素=%d,内存地址=%d\n",i+1,*p,p);
		p++;
	}
}

程序输出结果如下图所示:

例3演示了如何使用指针遍历数组元素。指针变量p指向数组元素data的首地址,在第一次fou循环时,p存储的值为16250656,存储在该地址的值为11,然后p做自增操作,p存储的地址为16250660,该地址为data数组第2个元素的内存地址,存储在该地址的值为21,此过程持续到for循环结束。

使用指针访问数组元素时,需要注意指针指向的是数组元素的内存地址,当把数组名称赋值给指针变量时,实际是把数组第1个元素的内存地址赋值给了指针变量,然后通过指针的加减算术运算让指针指向数组不同元素的内存地址。在进行指针加减算术运算时,要特别注意指针不能越界,不能让指针指向数组元素以外的内存地址,否则程序会抛出异常。

 

代码在线纠错(通义千问 qwen-max)

支持粘贴多个代码文件,提交后由阿里云通义千问自动分析代码漏洞、语法错误、逻辑问题并给出修改建议。
您已解锁 AI 代码纠错功能,可正常使用!

评论区

登录 后发表评论
暂无评论