二级指针做输入第二种数据类型

本文介绍了一个使用C语言实现的简单程序,该程序能够对字符数组进行排序并打印排序前后的结果。通过定义两个函数:`sort_array`用于数组排序,`print_array`用于打印数组内容,展示了基本的字符串操作技巧,如比较和复制。
#define _CRT_SECURE_NO_WARNINGS
#include "stdio.h"
#include "string.h"

//打印函数---打印数组
void print_array(char *string_word, char array[10][20], int num)
{
    int i = 0;
    printf("%s\n", string_word);
    for (i = 0; i < num; i++)
    {
        printf("%s\n", *(array + i));
    }

}
int sort_array(char array[10][20], int num)
{
    int i, j = 0;
    char temp[20];

    if (array == NULL || num < 0)
    {
        return -1;
    }
    for (i = 0; i < num; i++)
    {
        for (j = i; j < num; j++)
        {
            if (strcmp(array[i], array[j])>0)
            {
                strcpy(temp, array[i]);
                strcpy(array[i], array[j]);
                strcpy(array[j], temp);
            }
        }
    }
    return 1;
}
void main()
{
    char a[10][20] = { "aaa", "11", "bb", "cc" };
    int i = 0, j = 0;
    int num;
    num = 3;
    print_array("排序之前", a, num);
    sort_array(a, num);
    print_array("排序之后", a, num);

}
<think>嗯,用户正在深入探讨C语言二级指针数据类型问题,这已经是关于二级指针的第二个问题了,看来ta在系统性地学习指针机制。用户上次询问的是二级指针的基本使用,这次聚焦在数据类型决定因素上,说明学习路径很清晰。仔细看用户这次的问题核心是“二级指针数据类型由什么决定”。结合用户提供的三个引用,其中引用[1]特别强调指针是泛型概念,需区分具体类型;引用[2]提到void*指针的特性;而引用[3]是计算机二级考试知识,相关性较弱。这说明用户希望从语言规范层面理解类型系统。用户可能正在编写需要泛型处理的代码(比如动态数据结构),或遇到了类型转换的问题。ta特意指出参考站内引用,说明需要权威解释。我注意到用户忽略了我上次回复中的“指向类型决定解引用操作”这一点,可能需要更强调。需要重点解释三个层次:定义时的显式类型声明、被指一级指针的类型约束、解引用时的类型转换规则。特别要区分普通指针与void指针的差异,因为引用[2]提到void*会丢失类型信息——这正好能解释二级指针的类型安全性问题。用户似乎对底层机制感兴趣,可以补充内存示意图:假如定义int**pp,内存中pp存储的是(int*)类型变量的地址,而*(pp)指向的必须是int类型数据。void**则不同,它像个“类型黑洞”需要强制转换。还要预防常见误区:有人以为二级指针本身有“固定类型”,其实它的类型完全取决于声明。比如FILE**和int**就是完全不同的类型系统,编译器会严格检查。这点在引用[1]的数组部分也有暗示。最后考虑设计两个例子对比:int**的安全使用和void**的风险操作。用户上次对链表示例反应良好,这次也可以沿用数据结构场景,比如展示在二叉树节点操作中类型严格性的重要性。</think> 在C语言中,二级指针数据类型由其**指向的一级指针的数据类型**决定。具体来说: ### 1. **数据类型定义规则** 二级指针的类型声明为 `T**`, 其中: - `T` 是它**最终指向的基础数据类型**(如 `int`, `char` 等) - `T*` 是它**直接指向的一级指针的数据类型** 例如: ```c int num = 10; int *ptr = &num; // 一级指针(int* 类型) int **pptr = &ptr; // 二级指针(int** 类型) ``` 此处 `pptr` 的数据类型是 `int**`,由以下因素决定: - `pptr` 指向 `ptr`(一级指针) - `ptr` 的类型是 `int*` - 因此 `pptr` 的数据类型是 `int**` ### 2. **关键决定因素** | **因素** | **说明** | **示例** | |------------------------|--------------------------------------------------------------------------|------------------------------| | **指向的一级指针类型** | 二级指针必须匹配一级指针的类型声明 | 若一级指针为 `float*`,则二级指针需为 `float**` | | **解引用后的操作** | 二级指针的最终操作对象类型必须与声明一致 | `int **pptr` 解引用后操作的是 `int` 类型数据 | | **类型系统约束** | 编译器会根据声明严格检查二级指针的赋值和解引用操作[^1] | `char **` 不能指向 `int*` 类型指针 | ### 3. **特殊场景:`void**`类型** ```c void *ptr; // 通用一级指针 void **pptr = &ptr; // 合法 int num = 10; ptr = &num; // 允许,void* 可接受任意地址 // **pptr = 20; // 错误!void** 无法直接解引用赋值 *(int*)*pptr = 20; // 需显式类型转换[^2] ``` - `void**` 属于“未完全类型”,不能直接解引用 - 必须转换为具体类型(如 `int**`)才能操作数据[^2] ### 4. **类型匹配验证实验** ```c #include <stdio.h> int main() { int a = 100; int *p1 = &a; int **p2 = &p1; // 正确:int* 匹配 int** char *str = "test"; // int **p3 = &str; // 编译错误:char* 与 int** 不兼容 printf("%d", **p2); // 输出100 return 0; } ``` ### 5. **核心结论** - **二级指针数据类型** = **指向的一级指针类型** + `*` - 类型安全性由编译器在以下环节保证: - 赋值时检查地址匹配性 - 解引用时验证操作对象的类型[^1] - `void**` 需手动类型转换才能操作数据[^2]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值