各种指针

*号

定义时

*号在定义时并不是取值的意思
int* p对于初学者来说较难为理解。尤其是“ * ”符号。我们用定义整形变量类比

int p = a; //定义一个整型变量,类型为int,里面存放的是a的值
cout << p; //输出a的值
int* p = &a; //定义一个整型指针变量,类型为int* ,里面存放的是a的地址,定义时,*其实是和int放一块
cout << p;   // 输出a的地址

取值时

*号如果不在定义变量时使用就是取值符,取出一个地址中的值

int a = 5;
int* p = &a;
cout << *p; //输出5

我们也可以通过这个符号直接修改该地址上的值

int a = 3;
int* p = &a;
*p = 5;
cout << a; //输出5 因为a所在地址的值被修改

指向变量的指针

这种指针是最基本的指针

int a = 3; //定义整形变量a
int* p = &a; //定义整形指针p存放a的地址

printf("a的值是%d\n" , a); 
printf("a的值是%d\n" , *p); //* 取值运算符 取出p地址里的值
printf("a的地址是%p\n" , &a);
printf("a的地址是%p\n" , p);

指向一维数组的指针

定义

变量申请内存是线性连续的
我们可以申请一个指针指向数组的第一个元素

int a[] = {1 , 2 , 3 , 4 , 5};
int* p = &a[0] //a[0]是数组的第一个元素,把他的地址赋给了指针

数组名称是首元素的地址
所以这样定义是一样的

int* p = a;

指针的移动

指针可以通过计算实现在内存上的移动

int a[] = {1 , 2 , 3};
int* p = a;
printf("%p" , p); //008FFB14 
printf("%d" , *p); //1
p = p + 1; //指针向下移动一格
printf("%p" , p); //008FFB18
printf("%d" , *p); //2

我们看到,指针加1,但在内存上移动了四个字节。
因为这是int型指针,其实就是移动到了数组的下一个数(int类型四个字节)

指向二维数组的指针

二维数组的指针怎么定义呢
假设我们定义一个3 * 4的数组a

int a[3][4]

二位数组的内存分配也是线性的
他的内存的分配是这样的
在这里插入图片描述
这里我们可以将a数组看成一个一维数组

普通一维数组a[3] 每一个数组存放着一个int类型的值
这里的一维数组a[3] 每一个数组存放着一个int[4]类型的值
这样说有点晦涩难懂

我们对一位数组定义指针时是这样的

int a[] = {1 , 2 , 3};
int *p = a; //p指向a[0] 是一个int类型

同理二维数组

int a[][3] = {{1 , 2 , 3} , {4 , 5 , 6}};
int (*p)[3] = a; //p指向a[0],是int[3]类型
//简单来说就是p指向一个长度为3个int , 刚才定义一维数组指针长度为一个int

注意的地方

int(*p)[3] 为什么要加括号 因为[]优先级与*一样,但是结合律从右向左,如果写成int *p[3]就成了一个长度为3的指针数组,也就是一个长度为三的数组其中每个数都是指针。

定义二维数组时,列数必须确定。

二维指针的取值

我们都知道,数组名是数组首元素的地址
所以

a = &a[0]
a[0] = &a[0][0] 

这两个都是正确的

我们可以通过两次取值获得a[0][0]

int a[3][3] = {0};
int (*p)[3] = a;
printf("%d" , **p); //两层取值

p = a 所以p中存放的是a[0]的地址,对他第一次取值*p就是a[0][0]的地址,再取一次才是a[0][0]的值

实现二维指针的移动

因为定义二维指针时,指针一指就是一行
所以

int a[3][3] = {0};
int (*p)[3] = a;
p = p + 1;

这样的操作移动三个int 相当于直接移动到了下一行,本来指向a[0] , 现在指向了a[1]
我们可以通过取一次地址获得a[1][0]的地址

int a[3][3] = {0};
int (*p)[3] = a;
int *p1 = *p;//p1指向a[0][0],因为p取了一次地址

通过这些例子加深一下

int a[3][3] = {{1 , 2 , 3} , {4 , 5 , 6} , {7 , 8 , 9}};
int (*p)[3] = a;
**(p + 1) // p先移到a[1]再取出a[1][0]的地址 再取出a[1][0]的地址 输出4
*(*p + 1) // p先取值,去除a[0][0]的地址,再移动到a[0][1] ,再取出a[0][1]得值,是2
*(*(p + 1) + 2) //p先移到a[1]在取出a[1][0]的地址,再移动到a[1][2],取出a[1][2]的值,是6

指向结构体的指针

我们定义一个结构体

struct Node
{
	int f , t , v;
};

然后我们可以用结构体来定义变量,每个变量有f,t,v三个成员
例如

struct Node f; //定义单个变量
struct Node e[23]//定义结构体数组

我们可以通过以下方式访问成员

f.v
e[i].t

定义指针

我们类比int指针

int a , b[23];
int *p1 = &a
int *p2 = b;

结构体指针

struct Node
{
	int f , t , v;
};
struct Node a , b[23];
struct Node *p1 = &a;
struct Node *p2 = b;

访问

对接刚才的代码,还是类比int型指针

*p1//访问a的值
*p2//访问b[0]的值
(*p1).f //访问a的成员f
(*p2).f //访问e[0]的成员f
*(p2 + 1).t //访问e[1]的成员t

结构体访问成员还有更简单的方法

使用成员运算符->

与上面代码对比

p1 -> f //访问a的成员f
p2 -> f //访问e[0]的成员f
(p2 + 1) -> t //访问e[1]的成员t

结构体指针和数组指针类似,只是结构体多了成员,访问时加上成员运算符就好了

指针与字符串

我们都学过,字符串是存在字符数组里的

char a[] = "fuck you";
char * ptr = a; //指向a[0];

字符串也是一个地址
我们还可以直接这样做

char *ptr = "deam";
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C语言中,指针是一种非常重要的概念,它可以用来存储变量的内存地址。通过指针,我们可以实现对变量的间接访问和操作。下面是C语言中各种指针定义函数的形式: 1. 指针变量的定义: 指针变量的定义需要指定指针所指向的数据类型。例如,定义一个指向整型变量的指针可以使用以下形式: ``` int *ptr; ``` 这里的`*`表示ptr是一个指针变量,它可以存储整型变量的地址。 2. 函数参数为指针: 在函数定义时,可以将参数声明为指针类型,以便在函数内部对参数进行修改。例如,定义一个函数来交换两个整型变量的值: ``` void swap(int *a, int *b) { int temp = *a; *a = *b; *b = temp; } ``` 在函数调用时,需要传递变量的地址作为参数。 3. 函数返回指针: 在C语言中,函数也可以返回指针类型的值。例如,定义一个函数来创建并返回一个动态分配的整型数组: ``` int* createArray(int size) { int *arr = (int*)malloc(size * sizeof(int)); // 对数组进行初始化或其他操作 return arr; } ``` 在函数内部使用`malloc`函数动态分配了一个整型数组,并返回了数组的首地址。 4. 指向函数的指针: 在C语言中,函数也可以被看作是一种特殊的变量,可以定义指向函数的指针。例如,定义一个指向函数的指针来调用不同的函数: ``` int add(int a, int b) { return a + b; } int subtract(int a, int b) { return a - b; } int main() { int (*funcPtr)(int, int); // 定义一个指向函数的指针 funcPtr = add; // 将函数add的地址赋给指针 int result = funcPtr(3, 2); // 通过指针调用函数add return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值