int a; int* a; int** a; int (*a)[]; int (*a)(int)

本文深入解析了C语言中的指针与数组概念,包括基本的int类型指针、多级指针、数组指针与指针数组的区别及应用场景。通过实例演示了不同类型的指针与数组的内存布局及使用方式。

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

a) int a;表示一个内存空间,这个空间用来存放一个整数(int);
b) int* a;表示一个内存空间,这个空间用来存放一个指针,这个指针指向一个存放整数的空间,即a)中提到的空间;
c) int** a;表示一个内存空间,这个空间用来存放一个指针,这个指针指向一个存放指针的空间,并且指向的这个空间中的指针,指向一个整数。也简单的说,指向了一个b)中提到的空间;
d) int (*a)[4];表示一个内存空间,这个空间用来存放一个指针,这个指针指向一个长度为4、类型为int的数组;和int** a的区别在于,++、+=1之后的结果不一样,其他用法基本相同。
以上四种类型见上图表示。
e) int (*a)(int);表示一个内存空间,这个空间用来存放一个指针,这个指针指向一个函数,这个函数有一个类型为int的参数,并且函数的返回类型也是int。

重点:

int *p[]和int (*p)[]

前者是指针数组,后者是指向数组的指针。更详细地说。

前: 指针数组;是一个元素全为指针的数组.
后: 数组指针;可以直接理解是指针,只是这个指针类型不是int也不是char而是 int [4]类型的数组.(可以结合函数指针一并看看......)

int*p[4]------p是一个指针数组,每一个指向一个int型的
int (*q)[4]---------q是一个指针,指向int[4]的数组。

定义涉及两个运算符:“*”(间接引用)、“[]”(下标),“[]”的优先级别大于“*”的优先级别。

  首先看int *p[4],“[]”的优先级别高,所以它首先是个大小为4的数组,即p[4];剩下的“int *”作为补充说明,即说明该数组的每一个元素为指向一个整型类型的指针。int *p[4]的存储结构如下:(存储方格横向排列或竖向排列没区别,只要按内存地址顺序排列就行,此处只是为画图方便)

 



    再看int (*q)[4]。它首先是个指针,即*q,剩下的“int [4]”作为补充说明,即说明指针q指向一个长度为4的数组。int (*q)[4]的存储结构如下:

请看以下定义:

int a[2][4]={{2,5,6,8},{22,55,66,88}};

int c[4]={5,8,9,4};

int d[3]={23,12,443};

int *p[4],(*q)[4];

q=a;

*p=c;

*(p+1)=d;

则int *p[4]和int (*q)[4]的存储数据为:

验证:

 

 

 

 

 

 

 

#include <stdio.h>

int main(void)

{

    int a[2][4]={{2,5,6,8},{22,55,66,88}};

    int c[4]={5,8,9,4};

    int d[3]={23,12,443};

    int *p[4],(*q)[4];

    q=a;

    *p=c;

    *(p+1)=d;

    int i,j;

    for(i=0;i<2;i++)

        for(j=0;j<4;j++)

       {

           if((i==1)&&(j==3)) break;

           printf("*(*(p+%d)+%d)=%d\n",i,j,*(*(p+i)+j));

       }

    puts("===============");

    for(i=0;i<2;i++)

       for(j=0;j<4;j++)

           printf("*(*(q+%d)+%d)=%d\n",i,j,*(*(q+i)+j));

   return 0;

}

 

输出结果为:

*(*(p+0)+0)=5

*(*(p+0)+1)=8

*(*(p+0)+2)=9

*(*(p+0)+3)=4

*(*(p+1)+0)=23

*(*(p+1)+1)=12

*(*(p+1)+2)=443

===============

*(*(q+0)+0)=2

*(*(q+0)+1)=5

*(*(q+0)+2)=6

*(*(q+0)+3)=8

*(*(q+1)+0)=22

*(*(q+1)+1)=55

*(*(q+1)+2)=66

*(*(q+1)+3)=88

转载于:https://www.cnblogs.com/xiaojingang/p/4451089.html

<think>我们正在讨论指针的赋值和初始化。用户的问题是关于C/C++中指针变量的赋值和初始化,具体例子是`int*a;`和`int*b=a;`。根据用户提供的引用和问题,我们需要解释指针的声明、初始化和赋值。引用[1]展示了未初始化指针的问题(内存分配但未初始化)以及栈溢出问题。引用[2]展示了指针操作的一个例子,包括指针的算术运算和解引用。引用[3]则提到了初始化顺序的重要性。用户问题:理解指针变量的赋值和初始化,特别是`int*a;`和`int*b=a;`。我们需要解释:1.指针的声明(如`int*a;`)意味着什么?此时指针`a`的值是什么?2.指针的初始化与赋值的区别。3.使用未初始化指针的危险(如引用[1]中提到的未初始化数据错误)。步骤:1.声明指针:`int*a;`声明了一个指向整数的指针,但此时`a`的值是未定义的(垃圾值),它指向一个不确定的内存地址。2.初始化指针:可以在声明的同时初始化,例如`int*a=NULL;`或`int*a=&some_int;`。3.赋值:在声明之后,使用赋值语句给指针赋值,例如`a=&some_int;`。4.另一个指针的赋值:`int*b=a;`表示将`b`初始化为`a`的值,即`b`指向`a`所指向的同一内存地址。注意:如果`a`在赋值给`b`之前没有被初始化(即没有指向一个有效的地址),那么`b`也将持有一个无效的地址,使用它会导致未定义行为。根据引用[1],使用未初始化的指针(如访问`array[100]`而array未初始化)会导致错误。因此,在示例中:int*a;//a未初始化,指向随机地址int*b=a;//b现在也指向同一个随机地址这样使用b是非常危险的。正确的做法是:intx=10;int*a=&x;//a指向xint*b=a;//b也指向x或者,如果暂时没有指向的对象,将其初始化为NULL:int*a=NULL;int*b=a;//b也是NULL然后在使用指针之前,确保它指向了有效的内存。另外,引用[3]提醒我们注意初始化顺序,但在指针的初始化中,我们同样要注意:在给一个指针赋值之前,确保被赋值的指针(如a)已经被正确初始化。因此,回答将围绕这些点展开。</think>### C/C++ 指针变量的赋值与初始化详解 在 C/C++ 中,指针的声明、初始化和赋值是核心概念。以下是针对 `int *a;` 和 `int *b = a;` 的解析: #### 1. **指针声明与未初始化风险** ```c int *a; // 声明指针变量 a ``` - `a` 是**未初始化**的指针,其存储的值是**随机内存地址**(垃圾值) - 直接解引用 `*a` 会导致**未定义行为**(UB),常见后果: - 段错误(访问非法内存) - 数据损坏(修改未知内存区域) - 隐蔽的运行时错误(如引用[1]中的 `uninitdata` 错误) > ⚠️ 引用[1] 的案例:`int res = array[100];` 因未初始化内存导致错误[^1] #### 2. **指针初始化与赋值** ```c int x = 10; // 整型变量 int *a = &x; // 正确初始化:a 指向 x 的地址 int *b = a; // 正确赋值:b 指向与 a 相同的地址 ``` - `int *b = a;` 的本质: - 将 `a` 存储的**内存地址值**复制给 `b` - `b` 和 `a` 成为指向同一内存位置的别名 - 通过 `*b` 修改值会影响 `*a` 和 `x` #### 3. **关键注意事项** - **初始化 ≠ 赋值**: ```c int *a; // 声明(未初始化) a = &x; // 赋值(需在声明后单独进行) ``` - **野指针风险**: ```c int *a; // 野指针 int *b = a; // b 同样成为野指针!危险! ``` - **合法操作示例**(引用[2]): ```c int arr[] = {1, 2, 3}; int *p = arr; // p 指向 arr[0] printf("%d", *p); // 合法输出:1 ``` #### 4. **初始化顺序重要性** 类成员指针初始化需注意声明顺序(引用[3]): ```cpp class Example { public: Example() : ptr2(nullptr), ptr1(ptr2) {} // 错误!ptr1 先于 ptr2 初始化 private: int* ptr1; // 声明顺序在前 int* ptr2; // 声明顺序在后 }; ``` > 成员变量按**声明顺序初始化**,与初始化列表顺序无关[^3] #### 5. **最佳实践** 1. **声明时初始化**: ```c int *a = nullptr; // C++11 或 NULL (C) ``` 2. **赋值前验证**: ```c if (a != nullptr) { int *b = a; // 安全赋值 } ``` 3. **避免悬空指针**: ```c int *a = new int(10); delete a; // 释放内存 a = nullptr; // 防止悬空指针 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值