指针的应用

指针对于C语言来说是非常重要的一环,可以说如果不会使用指针就说明没有真正掌握C语言。现在进一步总结指针,希望对其有更深层次的理解。

★别名陷阱

●什么是别名?

int temp = 3;
int *p,*q;
p = &temp;
q = &temp; 

对于一块内存来说,有多个指针同时指向这块内存,这多个指针中的每一个指针都是其他指针的别名。想上面这段代码,其中p是q的别名;同样q也是p的别名。

●别名陷阱

对于指针来讲,对指针操作就会直接操作指针指向的内存的内容。例如上面代码,如果对p指向的内存进行赋值*p = 5;那么该内存的值就会变成5,这样一来q指向的内存中的数值也会发生变化,内存中的值由3变成5。尤其在优化程序的时候,会造成一些比较隐蔽的错误,因此要十分的小心。

#include <stdio.h>
#define a *p
#define b *q
int main(void)
{
    int x;
    int *p,*q;
    p = &x;
    q = &x;
    a = 2;
    b = 3;
    printf("%d",a + b);

    return 0;
}

像上面这个程序a+b的值为6,就是因为b=3;这条语句修改了变量x存储的内容,而p和q都同时指向x,使*p = 3,最后使得a+b=6

★数组指针

C语言中,一个指针变量可以指向一个数组,这样的指针叫做数组指针。例如:

int (*p)[5];表示p是一个指针,指向一个数组对象,该数组是一个拥有5个整形元素的数组。因此,p+1时p移动的字节数应该等于p所指向的数组对象的字节数。像上面这个指针应当移动sizeof(int)*5。

个字节。

#include<stdio.h>

int main(void)
{
    int a[5] = {1,2,3,4,5};
    int (*p)[5];
    int *ptr;

    p = &a;
    ptr = (int *)(p + 1);
    printf("%d",*(ptr - 1));
    return 0;
} 

输出的结果是:5。分析一下原因,p是数组指针,则p+1指向的是a[5]。那么*(ptr-1)为什么是4呢?是因为ptr并非是数组指针而是整形指针。ptr = (int *)(p +1)就是将数组指针转换成整形指针。

区别:数组指针和指针数组

数组指针是一个指针,它指向数组;指针数组是一个数组,只不过数组中的每个元素都是指针。

★指针的指针

C语言中,指针可以指向指针,成为指针的指针。

int **p;表示定义一个指针变量,它指向的是另一个指针变量,这个指针变量又指向一个整形变量。

#include <stdio.h>

int main(void)
{
    int a;
    int *p;
    int **q;

    a = 100;
    p = &a;
    q = &p;

    printf("%d\n",a);
    printf("0x%x\n",*p);
    printf("0x%x\n",*q);
    //system("pause");
    return 0;
}

★指针类型的意义

指针的本质是一个无符号的整数,代表一个内存单元的单元号。但是在定义一个指针变量的同时,往往会声明该指针变量所指向的数据类型:int *p,表示该指针变量p指向的是一个整形。其作用是告知编译器需要从该地址处向后看多少个字节,把这些字节当做一个对象来看待。

★void*型指针

void*指针表示一个任意类型的指针,其可以指向任意一个类型的内存单元。

指针类型的意义在于使编译器可以知道从该指针所表示的地址开始,向后把多少个字节看成一个整体。任意类型的指针不能告诉编译器该向后看多少个字节,那么也就无法引用任意类型指针所指向的数据,void*类型似乎没有什么意义。但如果编译器不知道用户要把指针指向的内容作什么用途的时候,void*指针就起到作用了。编译器认为一块内存用户做什么都是合法的,那么这块内存的指针就是任意类型的。

有一个例子是:malloc函数分配一块内存后,得到这块内存的首地址,返回的就是void*类型的指针。

指针的本质是一个无符号的整数,从理论上将指针和一个整数的比较应该是没有问题的,但是C语言编译器同样不允许两者进行比较。因此在比较一个指针和一个整形数据时,首先要做的就是将整形数据转换为该指针类型,之后再进行比较。

指针的应用

时间: 2024-11-05 11:37:38

指针的应用的相关文章

[c/c++] programming之路(17)、高级指针

一.二级指针 二级指针的作用:1.函数改变外部变量指针2.外挂改变一个指针的值 1 #include<stdio.h> 2 #include<stdlib.h> 3 4 void main(){ 5 int a = 10; 6 int b = 20; 7 int *p1 = &a; 8 int *p2 = &b; 9 int **pp = &p1; 10 printf("%d,", **pp); 11 printf("\n%x,

C++学习笔记----2.4 C++引用在本质上是什么,它和指针到底有什么区别

从概念上讲.指针从本质上讲就是存放变量地址的一个变量,在逻辑上是独立的,它可以被改变,包括其所指向的地址的改变和其指向的地址中所存放的数据的改变. 而引用是一个别名,它在逻辑上不是独立的,它的存在具有依附性,所以引用必须在一开始就被初始化,而且其引用的对象在其整个生命周期中是不能被改变的(自始至终只能依附于同一个变量). 在C++中,指针和引用经常用于函数的参数传递,然而,指针传递参数和引用传递参数是有本质上的不同的: 指针传递参数本质上是值传递的方式,它所传递的是一个地址值.值传递过程中,被调

【转】父类子类指针相互转换问题

1.当自己的类指针指向自己类的对象时,无论调用的是虚函数还是实函数,其调用的都是自己的: 2.当指向父类对象的父类指针被强制转换成子类指针时候,子类指针调用函数时,只有非重写函数是自己的,虚函数是父类的: 3.当指向子类对象的子类指针被强制转换成父类指针的时候,也就是父类指针指向子类对象,此时,父类指针调用的虚函数都是子类的,而非虚函数都是自己的. 将上面三句话总结成一句话就是:当父类子类有同名非虚函数的时候,调用的是转换后的指针类型的函数: 当父类子类有同名虚函数的时候呢,调用的是指针转换前指

C++ Primer 学习笔记与思考_7 void和void*指针的使用方法

(一)void的含义 void的字面意思是"无类型",void差点儿仅仅有"凝视"和限制程序的作用,由于从来没有人会定义一个void变量,让我们试着来定义: void a; 这行语句编译时会出错.提示"illegal use of type 'void'".只是.即使void a的编译不会出错.它也没有不论什么实际意义. void真正发挥的作用在于: (1) 对函数返回的限定: (2) 对函数參数的限定. int f(void); equal t

当this指针成为指向之类的基类指针时,也能形成多态

this指针: 1)对象中没有函数,只有成员变量 2)对象调用函数,通过this指针告诉函数是哪个对象自己谁. 1 #include<iostream> 2 using namespace std; 3 class Shape 4 { 5 public: 6 //void cal_display(Shape* this) 7 void cal_display(){ 8 display(); 9 this->display(); 10 } 11 private: 12 virtual vo

指针x(超简单的x)

指针! 1 #include<cstdio> 2 #include<iostream> 3 4 using namespace std; 5 6 /* 7 相加或者相乘 8 */ 9 10 int main() 11 { 12 int a,b,s,t; 13 cin>>a>>b; 14 int *p; 15 p=&a; 16 int *q; 17 q=&b; 18 s=(*p)+(*q); 19 t=(*p)*(*q); 20 printf(

二重指针实现排序

1 //双指针对十个数排序 2 3 #include <stdio.h> 4 #include <stdlib.h> 5 #define N 8 6 //2017.3.5 7 int main() 8 { 9 //初始化数组 赋值N个数 用指针数组指向 10 int num[N]; 11 int *pNum[N]; 12 int **p = NULL; 13 for (int i = 0; i < N; i++) 14 { 15 num[i] = rand() % 100;/

c指针-专题

六---指针 内存和地址怎么理解呢? 机器中有一些位置,每一个位置被称为[字节]/byte,许多现代机器上,每个字节包含8个位.更大内存单位[字],通常包含2个或4个字节组成. 一个字包含4个字节,它的地址是什么? 他仍然只有一个地址,是最左边还是最右边的那个字节的位置,取决于机器. 机器事实-关于整型的起始位置: 在要求边界对齐(boundaryalignment)的机器上,整型存储的起始位置只能是某些特定的字节,通常是2或4的倍数. 变量名和地址关系? 所有高级语言的特性之一,就是通过名字而

智能指针的原理和简单实现

什么是智能指针? 智能指针实质上是一个类,定义一个类来封装资源的分配和释放.这个类的构造函数中传入一个指针,完成资源的分配和初始化.在析构函数中释放传入的该指针,完成资源的释放. 为什么要用智能指针? 智能指针就是智能,自动化的管理指针所指向的动态资源. 例如以下情况:代码中经常会忘记释放动态开辟的内存资源,导致内存泄露. // case1 void Test2() {  int* p1 = new int(2);  bool isEnd = true;  //...  if (isEnd)  

单继承与多继承中的虚函数表和虚函数指针

首先,我们了解一下何为单继承,何为多继承?? 单继承:一个子类只有一个直接父类. 多继承:一个子类有两个或多个直接父类. 单继承中的虚函数表分析: 示例程序: #include <iostream> using namespace std; typedef void(*FUNC)(); class Base { public: virtual void func1() { cout << "Base::func1()" << endl; } virt