C/C++指针的一些概念总结

什么是指针?
指针是一个变量,其值为另一个变量的地址,即,内存位置的直接地址。就像其他变量或常量一样,必须在使用指针存储其他变量地址之前,对其进行声明。指针变量声明的一般形式为:

type *var-name;

type 是指针的基类型,它必须是一个有效的 数据类型,var-name 是指针变量的名称。用来声明指针的星号 * 与乘法中使用的星号是相同的。但是,在这个语句中,星号是用来指定一个变量是指针。以下是有效的指针声明:

int    *ip;    /* 一个整型的指针 */
double *dp;    /* 一个 double 型的指针 */
float  *fp;    /* 一个浮点型的指针 */
char   *ch;    /* 一个字符型的指针 */

所有指针的值的实际数据类型,不管是整型、浮点型、字符型,还是其他的数据类型,都是一样的,都是一个代表内存地址的长的十六进制数。不同数据类型的指针之间唯一的不同是,指针所指向的变量或常量的数据类型不同。
介绍一些基本概念。
1、Null指针:NULL 指针是一个定义在标准库中的值为零的常量。
NULL 指针是一个定义在标准库中的值为零的常量。
例子:

#include <iostream>
using namespace std;
int main ()
{
   int  *ptr = NULL;
   cout << "ptr 的值是 " << ptr ;
   return 0;
}

运行结果:

ptr 的值是 0

需要注意的是:

  1. 1、如需检查一个空指针,可以使用 if 语句
if(ptr)     /* 如果 ptr 非空,则完成 */
if(!ptr)    /* 如果 ptr 为空,则完成 */
  1. 2、如果所有未使用的指针都被赋予空值,同时避免使用空指针,就可以防止误用一个未初始化的指针。很多时候,未初始化的变量存有一些垃圾值,导致程序难以调试。

2、指针的算术运算:指针是一个用数值表示的地址。因此,您可以对指针执行算术运算。可以对指针进行四种算术运算:++、–、+、-。
只需注意:

2.1.指针指向数组的时候,不可以加 &
2.2. 指针指向数组中某一元素时要用 &
例子:

short int height[10]; //int型的数组(short int 每个数据2字节)
cout <<  "height       "<< height << endl 
     <<  "height+1     "<< height + 1 << endl
     <<  "&height[0]   " <<  &height[0] << endl
     <<  "&height+1    "<< &height + 1<< endl
     <<  "height+9     "<< height+9 << endl
     << "height+10    " << height + 10 << endl;

运行结果:

height       0136F900
height+1     0136F902
&height[0]   0136F900
&height+1    0136F914
height+9     0136F912
height+10    0136F914

结论:

 height 与 &height[0] 值相等。
 height+1 = height + 2 字节 = height + 1short int 也即 一个数组元素。
 height+9 为 height[] 中最后一个元素的地址,height+10 为该数组结束后的第一个地址。
 &height +1=height+10,即执行 &height+1 的结果是地址跳到整个数组之后第一个地址。

3、指针和数组之间的关系
指针和数组在很多情况下是可以互换的。例如,一个指向数组开头的指针,可以通过使用指针的算术运算或数组索引来访问数组。
然而,指针和数组并不是完全互换的。
例子:

#include <iostream>
using namespace std;
const int MAX = 3;
int main ()
{
   int  var[MAX] = {10, 100, 200};
   for (int i = 0; i < MAX; i++)
   {
      *var = i;    // 这是正确的语法
      var++;       // 这是不正确的
   }
   return 0;
}

把指针运算符 * 应用到 var 上是完全可以的,但修改 var 的值是非法的。这是因为 var 是一个指向数组开头的常量,不能作为左值。
由于一个数组名对应一个指针常量,只要不改变数组的值,仍然可以用指针形式的表达式。
例:*(var + 2) = 500;

4、指针数组:
一个指向整数的指针数组的声明:

int *ptr[MAX];//把 ptr 声明为一个数组,由 MAX 个整数指针组成。因此,ptr 中的每个元素,都是一个指向 int 值的指针

例1:

#include <iostream>
 
using namespace std;
const int MAX = 3;
 
int main ()
{
   int  var[MAX] = {10, 100, 200};
   int *ptr[MAX];
   for (int i = 0; i < MAX; i++)
   {
      ptr[i] = &var[i]; // 赋值为整数的地址
   }
   for (int i = 0; i < MAX; i++)
   {
      cout << "Value of var[" << i << "] = ";
      cout << *ptr[i] << endl;
   }
   return 0;
}

运行结果:

Value of var[0] = 10
Value of var[1] = 100
Value of var[2] = 200

例2:

#include <iostream>
using namespace std;
const int MAX = 4;
int main() {
    const char *names[MAX] = {
        "Zara Ali",
        "Hina Ali",
        "Nuha Ali",
        "Sara Ali",
    };
    for (int i = 0; i < MAX; i++) {
        cout << " --- names[i]              = " << names[i] << endl;
        cout << " --- *names[i]             = " << *names[i] << endl;
        cout << endl;
        cout << " --- (*names[i] + 1)       = " << (*names[i] + 1) << endl;
        cout << " --- (char)(*names[i] + 1) = " << (char)(*names[i] + 1) << endl;
        cout << " ------------------------------------ " << endl << endl << endl << endl;
    }
    return 0;
}

运行结果:

 --- names[i]              = Zara Ali
 --- *names[i]             = Z

 --- (*names[i] + 1)       = 91
 --- (char)(*names[i] + 1) = [
 ------------------------------------ 
 
 --- names[i]              = Hina Ali
 --- *names[i]             = H

 --- (*names[i] + 1)       = 73
 --- (char)(*names[i] + 1) = I
 ------------------------------------ 
 
 --- names[i]              = Nuha Ali
 --- *names[i]             = N

 --- (*names[i] + 1)       = 79
 --- (char)(*names[i] + 1) = O
 ------------------------------------ 
 
 --- names[i]              = Sara Ali
 --- *names[i]             = S

 --- (*names[i] + 1)       = 84
 --- (char)(*names[i] + 1) = T
 ------------------------------------

注意:
*char names[MAX] 是指针数组, 它的本质是存储指针的数组, 既存储 char 类型的指针的数组, 数组内的每个元素都是一个指针指向一个存储 char 类型的地址:

区分指针数组(int *ptr[3] )和数组指针(int (*ptr)[3])。

5、指向指针的指针(多级间接寻址)
指向指针的指针是一种多级间接寻址的形式,或者说是一个指针链。通常,一个指针包含一个变量的地址。当我们定义一个指向指针的指针时,第一个指针包含了第二个指针的地址,第二个指针指向包含实际值的位置。
在这里插入图片描述
下面声明了一个指向 int 类型指针的指针:int **var;
当一个目标值被一个指针间接指向到另一个指针时,访问这个值需要使用两个星号运算符:
例:

#include <iostream>
 
using namespace std;
 
int main ()
{
    int  var;
    int  *ptr;
    int  **pptr;
 
    var = 3000;
    ptr = &var; // 获取 var 的地址
    pptr = &ptr; // 使用运算符 & 获取 ptr 的地址
 
    // 使用 pptr 获取值
    cout << "var 值为 :" << var << endl;
    cout << "*ptr 值为:" << *ptr << endl;
    cout << "**pptr 值为:" << **pptr << endl;
    cout << "var 地址为 :" << &var << endl;
    cout << "ptr=&var 值为var的地址:" << ptr << endl;
    cout << "ptr地址为:" << &ptr << endl;
    cout << "*pptr=ptr=&var  值为var的地址:" << *pptr << endl;
    cout << "pptr 地址为:" << &pptr << endl;
 
    return 0;
}

运行结果:

var 值为 :3000
*ptr 值为:3000
**pptr 值为:3000
var 地址为 :0x7fffc1bc04ac
ptr=&var 值为var的地址:0x7fffc1bc04ac
ptr地址为:0x7fffc1bc04a0
*pptr=ptr=&var  值为var的地址:0x7fffc1bc04ac
pptr 地址为:0x7fffc1bc0498

6、传递指针给函数
例:

#include <iostream>
using namespace std;
 
// 函数声明
void getAverage(int *arr, int size,double *avg);
 
int main ()
{
   int balance[5] = {1000, 2, 3, 17, 50};  // 带有 5 个元素的整型数组
   double avg;
   getAverage(balance, 5, &avg ) ;    // 传递一个指向数组的指针作为参数
   cout << "Average value is: " << avg << endl; // 输出返回值
   return 0;
}

void getAverage(int *arr, int size,double *avg)    //再次运用函数,使得sum得以累加
{
  int    i, sum = 0;        
  for (i = 0; i < size; ++i)
  {
    sum += arr[i];
   }
  *avg = double(sum) / size;    //求平均
}

运行结果:

Average value is: 214.4

7、从函数返回指针
参见:https://blog.csdn.net/ouzhiqi9007/article/details/107134427

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值