指针的基础使用
什么类型指针 指向什么类型的
什么类型指针 保存什么类型变量的地址
以下为指针引用与解引用的使用示例
#if 0
#include <stdio.h>
int main() {
double a = 1.1, b = 2.2;
double* p = &a, * q = &b;
double** s = &p, ** t = &q;
**s = 3.3;
*t = &a;
p = &b;//*s =&b;
return 0;
}
#endif
#if 0
#include <stdio.h>
void swap(int* pa, int* pb) {
int temp = *pa;
*pa = *pb;
*pb = temp;
}
int main() {
int a = 10, b = 20;
swap(&a, &b);
printf("%d,%d", a, b);
return 0;
}
#endif
指针的大小和平台有关系
x86---4字节
x64---8字节
指针+1的能力(数组的本质arr[i]; --->*(arr+i);)
例题
#include <stdio.h>
int main() {
int arr[] = { 1,2,3,4 };
int* p = arr;
printf("%d,%d,%d,%d", arr[1], p[1], *(p + 1), *(arr+1));
//2,2,2,2
return 0;
}
在一个连续的内存空间对指针加一本质为让其挪动指向类型所占内存个数
int*p p+n-------p+n*sizeof(int)<加一为加4字节>
double*q q+n--------q+n*sizeof(double)<加一为加8个字节>
const 和一级指针结合
int a = 10,b = 20;
const int* p =&a;
//const 放在指针前,限定指针指向的值不可被修改(*p = 10)
int* const g =&b;
//const 放在指针后,限定指针本身不可被修改
*p = 20; //error
*q = 10; //right
p = &b; //right
q = &a; //error
const int* const s = &a;
*s = 20; //error
s = &b; //error
指针加一例题
#include <stdio.h>
int main() {
int arr[10] = { 12, 23, 34, 45, 56, 67, 78, 89, 90, 100 };
int* p = arr;
int x = 0, y = 0;
x = *p++;//12指针先赋值后偏移
y = *p;//指针加一偏移四字节23
printf("x = %d y = %d \n", x, y);
x = ++ * p;//23+1=24且arr[1]被修改为24
y = *p;//24指针未动
printf("x = %d y = %d \n", x, y);
x = *++p;//34指针先偏移再赋值
y = *p;//34
printf("x = %d y = %d \n", x, y);
return 0;
}
自己的小结:++只要挨着p就是对指针的偏移1,反之则是都整型数据的+1;
指针与指针直接的运算(只能相减,不能相加)
例题用指针-指针的特性求数组长度
#include <stdio.h>
int my_strlen(const char *p) {
const char* q = p;
while (*q!= '\0') {
q++;
}
return (q-p);
}
int main() {
char str[20] = "hello";
int len = my_strlen(str);
printf("%d", len);
return 0;
}
指针数组
声明指针数组本质上是一个存放地址值的数组
其中的常量均为date区里的存放的为固定不可修改的
brr是在栈上创建的数组偏移一个为4字节(指针变量的大小为4字节x86)
brr里存放的地址则指向date区里的常量地址
const char* brr[l]= "hello","world","123";
//只能为char?*brr?int类型能存放在Date区里面吗?有什么用?
可以为任何类型且存放的变量的地址不一定是在data区里面的,后期项目里面会使用
解引用和之前的一样
数组指针
p是一个指向n个元素的整型数组的指针
例题
#include <stdio.h>
int main() {
int arr[4] = { 1,2,3,4 };
int(*p)[4] = &arr;
printf("%p\n%p\n%p\n%p", arr, p[0], &p[0], p[1]);
//前三个一样的最后一个和前三个差4*4=16个字节
return 0;
}
数组指针+1偏移指针数组
函数指针
一个指向函数的指针例题如下
#include <stdio.h>
int add(int a, int b) { return a + b; }
int mul(int a, int b) { return a * b; }
int main() {
int (*p)(int, int) = add;//声明一个指针指向add函数
int res = p(1, 2);//指针p的使用
p = mul;//修改指针指向
int num = p(1, 2);
printf("%d\n%d", res, num);
return 0;
}
#include <stdio.h>
void add(int, double) {
printf("调用void add(int, double)\n");
}
void fun(int a, void(*p)(int, double)) {
p(a, 1.0);
}
int main() {
fun(1, add);//此处add函数不可加形参
}
typedef源码中常用的重命名
#include <stdio.h>
int add(int a, int b) { return a + b; }
int mul(int a, int b) { return a * b; }
typedef unsigned long long uint64;//重命名声明
typedef int (*p)(int, int);//重命名函数指针
int main() {
uint64 num = 100;//num为un longlong类型
p p1 = add;//p1为函数指针指向add函数
p p2 = mul;//p2为函数指针指向mul函数
int res = p1(1, 2);
printf("%d", res);
return 0;
}