默认计划
491人加入学习
(0人评价)
【研发工程师】C语言程序设计
价格 ¥ 970.00
该课程属于 名企研发核心能力课 请加入后再学习

指针(变量):变量有的性质,指针都有。

变量作用:存值,有大小、地址。有类型

 

指针变量,也是变量

指针变量,也是变量

指针变量,也是变量

 

指针变量占多数字节?

看OS的位数32位、64位。

32位占4B,64位占8B

地址是按照字节标号的,一个字节给一个地址,从0开始,比如32位的内存范围是:0 ~ 2^32 - 1,是4GB的大小

 

指针变量本身自己也有地址。

 

取变量地址时,取相关变量的首地址(编号最小的地址)

 

int a;
int *p = &a;
int **p1 = p; // 指向指针的指针

cout << p; //输出的是地址
cout << *p; // 输出的是p地址里面的值

 

指针变量前面的数据类型,表示指向该数据类型变量的地址。

 

int *p;
char *q;
//p和q的所占字节数相同。

 

指针变量可以参与运算 + -

如:

int *p = NULL;

// p + 1就是地址向后加了4B,向不同类型后面+1个类型的字节大小。

---------------------------------------------

// 等价转换
*p <=> a(原始变量)
p + 1 <=> &p[1]
p->filed <=> (*p).filed <=> a.filed

-> 间接引用

.  直接引用

----------------------------------------

题目:

struct Data {

    int x, y;

};

struct Data a[2], *p = a;

尽可能的多的形式表示a[1].x 

#include <iostream>
using namespace std;

struct Data {
    int x, y;
};

Data a[2], *p = a;

int main() {
    a[0].x = 111, a[0].y = 222;
    a[1].x = 333, a[1].y = 444;

    cout << a[1].x << endl;                 // 直接访问数组元素
    cout << p[1].x << endl;                 // 使用指针数组下标访问

    cout << (&a[1])->x << endl;             // 数组下标和指针偏移的结合
    cout << (&p[1])->x << endl;             // 通过指针偏移访问
    
    cout << (p + 1)->x << endl;             // 使用指针算术结合结构体指针访问
    cout << (*(p + 1)).x << endl;           // 使用指针算术结合解引用操作访问

    cout << (a + 1)->x << endl;             // 使用数组指针算术访问
    cout << (*(a + 1)).x << endl;           // 使用数组指针解引用访问

    cout << *(&a[0].x + 2) << endl;         // 通过偏移结构体成员的地址
    cout << *(&p[0].x + 2) << endl;         // 通过偏移结构体成员的地址

    cout << (&a[0] + 1)->x << endl;         // 使用地址运算符和指针算术访问
    cout << (*(&a[0] + 1)).x << endl;       // 使用地址运算符和解引用访问

    cout << (&p[0] + 1)->x << endl;         // 使用地址运算符和指针算术访问
    cout << (*(&p[0] + 1)).x << endl;       // 使用地址运算符和解引用访问

    cout << *((int *)a + 2) << endl;        // 强制转换类型并进行指针算术访问
    cout << ((int *)a + 2)[0] << endl;      // 强制转换类型并当成数组访问
    cout << ((int *)a)[2] << endl;

    cout << *((int *)p + 2) << endl;        // 使用强制类型转换和指针算术访问
    cout << ((int *)p + 2)[0] << endl;
    cout << ((int *)p)[2] << endl;
  
    // 新的方法,使用char*进行偏移然后转换为Data*
    cout << ((Data*)((char*)a + sizeof(Data)))->x << endl;  // 套娃写法
    cout << ((Data*)((char*)p + sizeof(Data)))->x << endl;

    return 0;
}

 

函数指针:也是指针,变量,用来存函数的地址。

int (*add)(int, int); // 函数指针变量(add),int类型的,必须加( ),否则引起歧义。
int* add(int, int);   // 指针函数的声明,返回值为int*

typedef int (*add)(int, int);

 

typedef用法:

内建类型的重命名:(类似#define)

typedef long long lint;

typedef char* pchar;

typedef unsiged char uchar;

 

结构体类型的重名:

typedef struct __node {

    int x, y;

} Node, *PNode;

命名了两个类型:

Node:是这个结构体的类型

*PNode:PNode是这个结构体类型的指针类型

**注意是类型,不是变量!**

 

函数指针命名:

typedef int (*func)(int);

变量:int (*func)(int);

类型:typedef int (*func)(int);

-------------------------------------------

int main();

int main(int argc, char *argv[]);

int main(int argc, char *argv[], char **env);

argc:接收的是外部传入命令行参数的个数。

*argv[]:存char*的一维数组,char*用来保存字符串的首地址。

**env:当前的环境变量。可当成二维的字符数组env[][],env所接收到的内容是:具体的每一个能够获取的环境变量字符串。

---------------------------------------------

 

求地址偏移量。

以8B作为空间对齐标准

//21.pointer.cpp
#include <stdio.h>

#define offset(T, x) { \
    T tmp; \
    (char *)&tmp.x - (char *)&tmp; \
}
// 花括号外侧加圆括号是为了获取最后一条语句的返回值
// #define offset(T, x) ({T tmp; (char *)&tmp.x - (char *)&tmp;})

struct Data {
    int a;
    char b;
    double c;
};

int main() {
    printf("%ld\n", offset(struct Data, a));
    printf("%ld\n", offset(struct Data, b));
    printf("%ld\n", offset(struct Data, c));
    return 0;
}

函数不能将数据类型作为参数传入,所以要用宏

升级写法:

#define offset(T, x) (long long)&(((T *)(NULL))->x)

①先(NULL)一个空地址

②将(NULL)强制类型转换为(T *)结构体类型的指针

③成员访问(T *)(NULL))->x

④取其地址&((T *)(NULL))->x)

⑤将其地址强制类型转换为(long long型)查看其偏移量。

-----------------------------------------------

定义变量类型typedef和#define的区别:

#include <stdio.h>

#define ppchar char *
typedef char * pchar;


int main() {
	pchar p1, p2;    
	ppchar p3, p4;  //实际是 char * p3, p4;
	printf("p1 = %lu, p2 = %lu\n", sizeof(p1), sizeof(p2));
	printf("p3 = %lu, p4 = %lu\n", sizeof(p3), sizeof(p4));
	/*
	p1 = 8, p2 = 8
	p3 = 8, p4 = 1
	*/
    return 0;
    
}

 

[展开全文]

授课教师

C++算法工程师

课程特色

视频(31)