指针的定义和初始化

本文详细介绍了C++中指针的基本概念,包括指针变量的定义、不同风格的声明方式、指针的有效值、初始化及复制操作约束等内容,并强调了初始化的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 每个指针都有一个与之关联的数据类型,该数据类型决定了指针所有指向的对象的类型。例如,一个int 型指针只能指向 int 型对象。


1.指针变量的定义


     C++语言使用 * 号把一个标识符声明为指针:

    

        vector<int>   *pvec;

        int        *p1, *p2;

        string    *pstring;

    提示:理解指针声明语句时,请从右向左阅读。


 2.另一种声明指针的风格


    在定义指针变量时,可用空格符号 * 与气候的标识符分别开来,如下:

          string*  ps;

 也就是说,该语句把ps定义为一个指向 string 类型对象的指针。

     这种指针声明风格容易引起这样的误解:把string * 理解为一种数据类型,认为在同意声明语句中定义的其他变量也指向 string 类型对象的指针。

      如果使用下面的语句 :

            string*  p1, p2;

       实际上只把ps1 定义为指针,而ps2并非指针,只是一个普通的string 对象而已。如果需要在一个声明语句中定义了两个指针,必须在每一个变量标识符前再加符号 * 声明:

             string* ps1,*ps2;


 3.指针的可能取值


       一个有效的指针必然是以下三种状态之一:1.保存一个特定对象的地址;2.指向某个对象后面的另一对象;3.是0值。若指针保存0值,表明它不指向任何对象。未初始化的指针是无效的,直到给该指针赋值后,才可以使用它。下面的定义是合法的:

               int  ival = 1024;

               int  *pi = 0;

               int  *pi2 = &ival;

               int  *pi3;

               pi = pi2;

               pi2 = 0;


 4.避免使用未初始化的指针


提示:很多运行时错误都源于使用了未初始化的指针。

     就像使用其他没有初始化的变量一样,使用未初始化的指针时的行为C++标准中并没有定义,它几乎总会导致运行时崩溃。然而,导致崩溃的这一原因很难发现。

      对于大多数的编译器来说,如果使用未初始化的指针,会将指针中存放的不确定值视为地址,然后操纵该内存地址中存放的位内容。使用未初始化的指针相当于操纵这个不确定地址中存储的基础数据。因此,在对未初始化的指针进行解引用时,通常会导致程序崩溃。

      C++语言无法检测指针是否未被初始化,也无法区分有效地址和由指针分配到的存储空间中存放的二进制位形成的地址。建议在使用之前初始化所有的变量,尤其是指针!


建议:如果可能的话,除非所指向的对象已经存在,否则不要先定义指针,这样可避免定义一个未初始化的指针。

       如果必须分开定义指针和其所指向的对象,则将指针初始化为0.因为编译器可检测出0值的指针,程序可判断出该指针并未指向一个对象。


 5.指针初始化和复制操作约束


      对指针进行初始化或赋值只能使用一下四种类型的值:

      (1)0值常量表达式,例如:在编译时可获得0值的整型const 对象或字面值常量0.

      (2)类型匹配的对象的地址。

      (3)另一对象之后的下一地址。

      (4)同类型的另一个有效指针。

        把 int 型变量赋值给指针是非法的,尽管此 int 型变量的值可能为0.但允许把数值 0 赋值给指针:

        int  ival;

        int  zero = 0;

        const  int c_ival = 0;

        int  *pi = ival;

        pi = zero;

        pi  = c_ival;

        pi = 0;

除了使用数值0外,还可以使用C++语言从C语言中继承下来的预处理变量NULL,该变量在cstdlib头文件中定义,其值为0.如果在代码中使用了这个预处理变量,则编译时会自动被数值0替换。因此,把指针初始化为NULL等效于初始化为0值:

                    int  *pi = NULL;// ok:equivalent  to  int *pi = 0;

正如其他预处理器变量一样,不可以使用NULL这个标识符给自定义的变量命名。


 6.void *指针


      C++提供了一种特殊的指针类型void *,它可以保存任何类型对象的地址:

            double  obj = 3.14;

            double  *pd = &obj;

            void *pv = &obj;

            pv =pd;  //pd can be a pointer to any type

void *表明该指针与一地址值相关,但不清楚存储在此地址上的对象的类型。

      void *指针只支持几种有限的操作:1.与另一个指针进行比较;2.向函数传递void*指针或从函数返回void * 指针;3.给另一个void*指针赋值。不允许使用void *指针操纵它所指向的对象。

        

<think>我们正在讨论C语言中的结构体指针定义初始化方法。根据引用内容,结构体指针定义包括两个步骤:定义结构体类型声明指向该结构体类型的指针变量。初始化则是将指针指向一个已存在的结构体变量(或数组元素)的地址,或者动态分配内存。参考引用:-引用[1]给出了结构体指针定义初始化示例:先定义一个结构体stu,然后定义一个结构体变量stu1并初始化,最后定义结构体指针pstu并初始化为stu1的地址。-引用[2]展示了结构体定义(Student)但没有直接展示指针初始化。-引用[3]说明了结构体指针可以指向结构体数组的第一个元素。我们将按照以下步骤讲解:1.定义结构体类型2.声明结构体指针3.初始化结构体指针(指向已存在变量或动态分配内存)同时,我们会提供两个示例:一个是指向已存在的结构体变量,另一个是指向动态分配的内存。在回答中,我们需要注意LaTeX格式(行内用$...$,独立公式用$$...$$),但当前问题不涉及数学公式,所以主要注意代码展示引用标注。最后,按照要求生成相关问题。</think> ### C语言结构体指针定义初始化详解 #### **一、结构体指针定义** 结构体指针用于存储结构体变量的内存地址,语法格式为: ```c struct 结构体名称 *指针变量名; ``` - `struct` 是关键字,不可省略 - 指针变量名前必须有`*`符号 - 结构体必须先定义才能声明指针[^1][^2] **示例定义**: ```c struct Student { // 定义结构体类型 int id; char name[50]; float gpa; }; struct Student *pStu; // 声明结构体指针 ``` #### **二、初始化方法** ##### 1. 指向已存在的结构体变量 ```c struct Student stu1 = {101, "Alice", 3.8}; // 创建结构体变量 struct Student *p = &stu1; // 将指针初始化为变量地址[^1] printf("学号: %d\n", (*p).id); // 传统访问方式 printf("姓名: %s\n", p->name); // 推荐箭头操作符 ``` ##### 2. 指向结构体数组元素 ```c struct Student class[3] = { {201, "Bob", 3.5}, {202, "Cathy", 3.9}, {203, "David", 4.0} }; struct Student *pArr = class; // 指针指向数组首地址[^3] for(int i=0; i<3; i++){ printf("GPA: %.1f\n", (pArr+i)->gpa); // 指针算术运算访问 } ``` ##### 3. 动态内存分配初始化 ```c struct Student *pNew = (struct Student*)malloc(sizeof(struct Student)); // 成员初始化 pNew->id = 301; strcpy(pNew->name, "Emma"); pNew->gpa = 3.7; free(pNew); // 使用后必须释放内存 ``` #### **三、核心操作语法** 1. **成员访问运算符**: - `(*指针).成员名` - `指针->成员名`(更简洁的等效写法)[^2] 2. **指针运算**: ```c p++; // 移动到下一个结构体(偏移量=sizeof(struct Student)) ``` #### **四、注意事项** 1. **内存安全**: - 指针初始化前禁止访问(避免野指针) - 动态分配内存必须配对`malloc/free` 2. **结构体对齐**: - `sizeof(struct Student)`通常大于成员大小之 - 使用`offsetof`宏获取成员偏移量 3. **常量指针**: ```c const struct Student *pConst; // 禁止通过指针修改结构体 ``` ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值