指针最基本的使用
void modify(int* a) //int *a=# 赋值操作,形参,实参类型一致 { *a = 1001; //*一级指针 } //在子函数中,修改普通的实参的值, //传的是普通实参的地址(一级指针),在子函数中修改是*一级指针 int main() { int num = 1; modify(&num); printf("%d\n", num); int aa = 1; int bb = 1001; return 0; } 在子函数中,修改的是*a交换a,b的值,使其可以在主函数当中输出
void Swap(int* a, int* b) //交换a,b的值,使其可以在主函数当中输出 { int temp = *a; *a = *b; *b = temp; } //子函数当中修改了函数的值 int main() { int aa = 1; int bb = 1001; Swap(&aa, &bb); //传参就系要传实参的地址 printf("a=%d,b=%d\n", aa, bb); return 0; }在子函数总,修改指针的实参的值,传的是指针实参的地址(二级指针),在子函数中修改是*二级指针
int g_num = 1001; void modifyPoint(int** p) //在当前函数中修改指针的指向,由p指向num改为p指向g_num { //在子函数总,修改指针的实参的值, //传的是指针实参的地址(二级指针),在子函数中修改是*二级指针 *p = &g_num; //修改p的指向需要p的地址,就要传二级指针**p } int main() { num = 1111; int* p = # modifyPoint(&p); printf("%d\n", *p); //returnPremer2(p); return 0; } 2.反回值是指针 2.1 不能返回局部变量地址 2.2 规定用int类型的返回变量,int*类型的返回变量的地址,int返回变量 int* returnNum() //合法 { return &g_num; } //int a 是局部变量 不能返回局部变量的地址 int* returnPremer(int a) //1 { return &a; //return 1对 return &1错 } int* returnPremer2(int* a) //传入的是指针变量的值,不是局部变量的地址 { return a; //所以返回指针变量的值 }数组中
//在数组中 void initArray(int array[], int arrayNum) //传数组的专用写法 { for (int i = 0; i < arrayNum; i++) { array[i] = i; } } void initArray2(int* array, int arrayNum) //传指针或地址的写法 //int array[],int* array两种写法等效 { //相当于传一级指针 for (int i = 0; i< arrayNum; i++)//array 等效于&array[0](第一的元素的地址) int *array { array[i] = i; } }字符串赋值溢出时报错,顺便教几个单词
动态内存申请的格式
void *malloc(size_t size); //void *说明使用malloc函数时需要强制转换释放格式
free(void *point);只申请一个变量内存
//只申请一个变量内存 int* pInt = (int*)malloc(sizeof(int)); //指针变成变量,有两种方式 //1.指向变量的地址 *pInt1001;//*+地址就是一个变量 //int* pVoid = NULL; //*pVoid=1001; *pVoid不能被改变,NULL是空,相当于0,是常量,常量不能改变 //2.申请堆内存,只要申请了堆内存,它就是一个变量动态内存申请的好处
int* malloNum() //所做的操作会被保留 { int* p = (int*)malloc(sizeof(int)); *p = 1002; return p; }申请一段内存: 数组
int arrayNum = 0; scanf("%d", &arrayNum); int* pArray = (int*)malloc(sizeof(int) * arrayNum); //pArray[5],申请数组 for (int i = 0; i < arrayNum; i++) { pArray[i] = i; printf("%d\t", pArray[i]); } printf("\n"); //释放一定要置空 free(pInt);//释放指针 pInt = NULL; free(pArray); pArray = NULL;通过二级指针去理解二维数组
int** makeArray2D(int row, int cols) { //int *array --->array[i] 存放多个整数 //int **p--->(*p)[i] 存放多个一级指针 //p[i]---> 存放多个整数 //二级指针如何变成二维数组 int **p = (int **)malloc(sizeof(int*) * row); //指针类型(int **), for (int i = 0; i < row; i++) { p[i] = (int*)malloc(sizeof(int) * cols); } return p; } int main() { //通过二级指针去理解二维数组 //二级指针如何变成二维数组 int** array2D = makeArray2D(2, 2); array2D[1][1] = 1001; printf("%d\n", array2D[1][1]); free(array2D); array2D = NULL; return 0; }释放问题:在哪里申请的, 在哪个位置释放
//释放问题: 在哪里申请的, 在哪个位置释放 int* pMove = (int*)malloc(sizeof(int) * 3); //正常的使用 pMove[0] = 1; pMove[1] = 2; pMove[2] = 3; //做了指针指向的改变 pMove++; //此时pMove指向pMove[1] //pMove[i]等效于 *(pMove+i) 指针的运算 printf("pMove[-1]=%d\n", pMove[-1]); //释放前要还原指针原来的指向 --pMove; free(pMove);//从哪里申请就要从哪里释放 pMove = NULL;其他释放函数
//1 //malloc申请的内存是没有初始化,存放的是垃圾值 //void * calloc(size_t count,size_t size); 申请内存过程中初始化 int* pMalloc = (int*)malloc(4 * sizeof(int)); memset(pMalloc, 0, sizeof(int) * 4); //设置内存每个字节的值 int* pCalloc = (int*)calloc(4, sizeof(int));//(4, sizeof(int))相当于(4 * sizeof(int)) //以上三句话中,前两句话相当于第三句话 free(pMalloc); //使用完后要释放 pMalloc = NULL;//一定要为空,否则成为野指针 free(pCalloc); pCalloc = NULL; //2 //为指针重新申请内存 //void *realloc(void *p,size_t size); int* pRealloc = (int*)malloc(sizeof(int) * 2); pRealloc[0] = 1; pRealloc[1] = 2; printf("%p\n", pRealloc + 1); printf("%p\n", pRealloc + 2); pRealloc=(int *)realloc(pRealloc, sizeof(int) * 4);//重新申请的空间一定要比上次的大 //该返回值指向重新申请的空间的首地址 pRealloc[2] = 3; pRealloc[3] = 4; printf("%p\n", pRealloc + 1); printf("%p\n", pRealloc + 2); for (int i = 0; i < 4; i++) { printf("%d\t", pRealloc[i]); } printf("\n"); free(pRealloc); pRealloc = NULL;指针数组 一般是用来操作字符串
//指针数组 int a = 1; int b = 2; int c = 3; int* pInt[3];//每一个pInt[i]都可以存放一个指针,数字类比较少用 //pInt[i] 多个一级指针 pInt[0] = &a; pInt[1] = &b; pInt[2] = &c; const char* p = "ILove";//一级指针可以操作一个字符串,所以常用指针数组操作多个字符串 const char* pStr[3] = {"ILove","IMissyou","wantyou"}; for (int i = 0; i < 3; i++) { puts(pStr[i]);//pStr[i]是一级指针,puts自动换行 //好处,每个字符串的申请空间可以不相同 }数组指针 可以表示二维数组 2.2.1 变成二维数组 2.2.2 当做二维数组的指针使用 传二维数组时的一个错误做法
void print(int array[][3], int row, int cols) { for (int i = 0; i < row; i++) { for (int j = 0; j < cols; j++) { printf("%d\t", array[i][j]); } printf("\n"); } } int main()//真正的二维数组其实不是二维指针 { int array[2][3] = { 1, 2, 3, 4, 5, 6 }; //“函数”:“int (*)[3]”与“int **”的间接级别不同 int **p = array; print(p, 2, 3); //按规矩来说其实本身不允许这样写 //c语言中可以运行,但是会有问题,如下图。但是c++中会报错 return 0; }当看到有以下问题时,将其当做错误代码处理
这些都是因为指针的类型不一致,一般情况下数组与二级指针是有区别的,所以一般情况下我们传的是数组指针 正确做法将后半段改为
int array[2][3] = { 1, 2, 3, 4, 5, 6 }; //数组指针 int (*p)[3] = array; //这里做了改变 //*优先跟p结合在一起,就形成了一个指针,这个指针是指向一个数组的,这个数组的长度是三 print(p, 2, 3);数组指针如何申请内存 变成二维数组
//数组指针如何申请? 让他变成二维数组 //(指针的类型)malloc(sizeof(指针所指向的类型)*n); //指针的类型:去掉变量 //指针所指向的类型:去掉变量名和* int(*pArray)[3] = (int(*)[3])malloc(sizeof(int[3]) * 2); //等效 int pArray[2][3]; for (int i = 0; i < 2; i++) { for (int j = 0; j < 3; j++) { pArray[i][j] = i + j; printf("%d\t", pArray[i][j]); } printf("\n"); } free(pArray); pArray = NULL;