C语言指针初试
指针注意事项
指针就是一个地址 它的大小为4字节(x86)或者8字节(x64)
* 就是取出指针里面的内容
& 就是取地址
对数据的操作有两种权限
读:用函数的副本机制
写:用指针来修改
指针的初始化
int num = 10;
int *p = #
printf("%d,%p",*p,p);
指针与指针变量的区别
指针:指针是一个地址,它可以表示一个地址,有多长,这块内存如何解析
指针变量:就是一个变量不知道如何解析这篇内存
p *p &p的区别
*p指向内存的值
p取指针的地址
&p指针变量
如果两个指针指向同一个地址
用于数据通信
int num = 10;
int *p = #
int *px = #
*px = 100;//这里*p的值也被修改成100
printf("%d,%p",*p,p);
printf("%d,%p",*px,px);
指针的运算
指针的运算只有在数组中才有意义
int arr[3] = {1,2,3};
int *p = arr;
printf("%d\n",*p);
//假设P的地址为300500
//p+1 的地址就是300504
p = p + 1;//这里的加一 在内存中是向前读了4(与数据类型匹配,如果是char则向前读1个字节)个字节
printf("%d\n",*p);
指针与数组
int arr[3] = {1,2,3};
int *p = arr;
//用下标的方式循环数组
for(int i = 0;i<3;i++)
{
printf("\n%d",a[i]);
}
//用指针的方式循环数组
for(int *p = a;p<a+3;p++)
{
printf("\n%d",*p);
}
数组的排序(指针)冒泡
用指针排序的时候更安全
如果通过第三个变量进行更改
如果电脑突然断电,数组里面的数据会发生改变
#include<stdio.h>
#include<stdlib.h>
#define N 3;
//这里需要注意数组没有副本机制
//冒泡排序法每一次选择最大的放在最后面
//排序的时候只需要循环N-1次
void _sort(int a[N])
{
for(int i = 0;i<N-1;i++)
{
for(int j = 0;j<N-1-i;j++)
{
if(*(a+j)>*(a+j+1)
{
int temp = *(a+j);
*(a+j) = *(a+j+1);
*(a+j+1) = temp;
}
}
}
}
int main()
{
int arr[N] = {7,3,5};
_sort(arr);
for(int i = 0;i<N;i++)
{
printf("%d\n",arr[i]);
}
return 0;
}
malloc realloc calloc的区别
malloc(size_t _Size) 分配内存 分配完内存后里面的数据并没有初始化
calloc(size_t _NumOfElements,size_t _NumOfElements)
分配完内存后初始化
realloc(void *_Memory,size_t _New_Size) 重新分配内存 如果后面有足够的内存直接用负责重新开辟内存
如果用这三个函数分配的内存在堆上,不会被回收 直到程序消亡后又OS自动回收
否则我们要用free(void *_Momory) 进行释放,并且将指针赋值为NULL
当数组为100万+以上的数据的时候我们就用malloc分配内存普通数组只能处理小数据,不废话上代码
这3个函数返回的是空指针类型:
空指针可以接受任何类型的指针,用于保存 地址但是空指针
不明确大小,无法读取内存里面的数据
这时候就需要 对空指针进行强制类型装换
#include<stdio.h>
#include<stdlib.h>
int main()
{
//假设我们要处理100万的数据
int num = 1000000;
//malloc realloc calloc 分配的是字节
//这里我们 求出int的大小用sizeof 然后乘以数量
//这里我们就分配了这么多的内存
int *p = (int *)malloc(sizeof(int) * num);
//我们对这片内存进行管理
/*for(int i = 0;i<num;i++)
{
p[i] = i;
}*/
//我们用高级的方法进行赋值,先定义个指针指向首地址
int i = 0;
for(int *px = p;px<p+num;px++)
{
*px = i;
i++;
}
//然后我们把数据显示出来 这里可能会有点慢毕竟100万条数据
for(int *px = p;px<p+num;px++)
{
printf("%d\n",*px);
}
//用完后释放内存 不能释放两次否则会报错
free(p);
p = NULL;//规范写法释放完后把指针赋值为NULL
return 0;
}
#include<stdio.h>
#include<stdlib.h>
void main()
{
int num = 100;
int *p = (int *)malloc(num * sizeof(int));//分配内存
for (int i = 0; i < num; i++)
{
p[i] = i;
}
int num1 = 100000;
int *px = (int *)realloc((void *)p, (num + num1) * sizeof(int));//重新分配
for (int i = num; i < num + num1; i++)
{
px[i] = i;
}
printf("%x", px);
free(px);
p = NULL;
px = NULL;
printf("------");
/*for (int i=0;i<num+num1;i++)
{
printf("%d\n", p[i]);
}*/
system("pause");
}
指针与函数 间接访问函数
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int * mindate(int a[],int n)
{
int *p = a;
for (int i = 0; i < n; i++)
{
if (*p > a[i]) {
p = &a[i];
}
}
return p;
}
int main()
{
//int * mindate(int a[],int n)把函数名直接换成指针
int * (*m)(int a[], int n) = mindate;//通过函数地址 间接调用函数
int *p = m(a, 5);//现在的P的地址在寄存器上存放如果执行下面一句代码则取*p没有意义会是一堆垃圾数据
//printf("-----------------------\n");
printf("%d\n", *p);
return 0;
}
//线性的方式访问2维数组
#include<stdio.h>
void main()
{
int a[3][3] = {1,2,3,4,5,6,7,8,9};
for (int *p = &a[0][0]; p < &a[0][0] + 9; p++)
{
printf("%d,%x\n", *p,p);
}
getchar();
}
一级指针与二级指针
//一级指针用来改变数据的
//二级指针用来改变一级指针的指向
//二级指针ps:比如你想追一个妹子,但是你又不好意思直接要他的联系方式这时候你就需要 找到妹子的闺蜜(二级指针)通过她来获取妹子的联系方式
//ps:比如你在北京找房子 这时候会有一个中介给你介绍房子让后你觉得他介绍的这家不好,这时候就需要让他换一家(二级指针改变中介的方向)
//二级指针经常用于游戏外挂 比如说
#include<stdio.h>
#include<stdlib.h>
int main()
{
int num = 100;
int num1 = 101;
int *p = #
printf("%d\n",*p);
int **px = &p;
*px = &num1;
printf("%d\n",*p);
return 0;
}
二级指针经常用于游戏外挂
#include<stdio.h>
#include<stdlib.h>
#include<Windows.h>
double bd = 10.8;
double db = 20.8;
void change(double *p) {
p = &db;
}
void changep(double **pp) {
*pp = &bd;
}
int main() {
int num = 100;
char ch1 = 'A', ch2 = 'B', ch3 = 'C';
char *p = &ch1;
printf("%x\n", &num);
printf("%x\n", &p);
//一般游戏的等级都是用地址保存的这时候我们需要用一个2级指针改变他的指向
printf("%x,%x,%x\n", &ch1,&ch2,&ch3);
while (1){
printf("我的血量%d,我的等级%c\n", num, *p);
Sleep(2000);
}
}
#include<stdio.h>
#include<stdlib.h>
#include<Windows.h>
_declspec(dllexport) void go(){
int * p = (int *)0x57fbb4;//找出血量的地址用一级指针进行更改
*p = 100120;
}
_declspec(dllexport) void goC() {
char **pp = (char **)0x57fbab;//找出等级的得知用二级指针进行更爱
*pp = (char *)0x57fb93;
}