#include<stdio.h>
#include<stdlib.h>
#include<string.h>
/*******************复习动态内存和指针*********************/
//**********************动态内存分配***********************
//动态分配一个值
int main()
{
int num = 20;//栈区
int* p = #
//自动申请到堆区,成功返回申请到的首地址,失败返回null
int* pn = (int*)malloc(sizeof(int));
if (pn == NULL)
{
printf("申请失败\n");
return -1;
}
*pn = 66;
printf("%d", *pn);
free(pn);
pn = NULL;//指针置空
//自己释放,释放完之后将指针置为空,防止下面误用,置空就不能用了
printf(" %d", *pn);
}
//动态分配一个数组-----可以用变量给数组大小赋值
int main()
{
int n = 15;
int* parr = (int*)malloc(sizeof(int) * n);
if (parr == NULL)
{
return -1;
}
memset(parr, 0, sizeof(int) * n);//把parr这片内存置0
for (int i = 0; i < n; i++)
{
//printf("%d\n", parr[i]);
//printf("%p\n", &parr[i]);
//printf("%d\n", *(parr + i));//parr+i,其中parr没有变
//printf("%d\n" ,* (parr++));//错误!!!!而这里parr自增变了:注意:不要改变动态内存分配了的指针的指向
}
free(parr);
parr = NULL;
}
//动态扩容数组
int main()
{
//int* pn = malloc(sizeof(int));
int* pn = calloc(3, sizeof(int));//自动初始化为0
if (pn == NULL)
{
return -1;
}
//*pn = 2;
//pn = realloc(pn, sizeof(int) * 3);
if (pn==NULL)
{
return -1;
}
//*(pn + 1) = 3;//起初是没有内存的,需要再申请
//*(pn + 2) = 3;
for (int i = 0; i < 3; i++)
{
//printf("%d\n", *(pn + i));//*(pn+i) = pn[i]
*(pn + i) = i;
}
int arr[5];
memcpy(arr, pn, 12);//逐个字节拷贝
for (int i = 0; i < 3; i++)
{
printf("%d\n", *(arr + i));
}
free(pn);
return 0;
}
//***************************大小端存储***************
int main()
{
int* p = malloc(4);
*p = 0x12345678;
//printf("%x", *p);
printf("%x", *(char*)p);
return 0;
}
*******************数组指针(一维数组)**********************
int main()
{
//普通变量
int num = 12;
int* p = #
//一维数组
int arr[5] = { 0 };
int* parr = arr;//第一种---第一个元素首地址
//下标法
for (int i = 0; i < 5; i++)
{
printf("%d", arr[i]);
}
//指针法
for (int i = 0; i < 5; i++)
{
printf("%d", *(parr + i));
printf("%d", *(arr + i));
//printf("%d", *(arr++));//数组名赋值给指针时会退化成首地址,不可变
}
//arr和&arr[0]的值一样,含义一样,但是用sizeof求大小时就不一样
printf("%d %d", sizeof(arr), sizeof(&arr[0]));
//parr = &arr[0];//第二种
//parr = &arr;//warning,虽然地址一样但是含义不一样
//int(*pa)[5] = &arr;//指向整个数组的指针
//printf("%p %p %p\n", arr, &arr[0], &arr);
//printf("%p %p %p\n", arr+1, &arr[0]+1, &arr+1);
}
***********************数组指针(二维数组)***************
int main()
{
int arr[2][3] = { 1,2,3,4,5,6 };
int(*p)[3] = arr;//二维数组指针
//下标法
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
printf("%d ", p[i][j]);
}
printf("\n");
}
//指针法
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
//printf("%d ", *(p[i]+j));
printf("%d ", *(*(p + i) + j));
}
printf("\n");
}
}
//**********************指针数组******************
int main()
{
int* arr[3] = { NULL };//存储的元素为指针的数组
//printf("%d", *arr[0]);//int *
for (int i = 0; i < 3; i++)
{
arr[i] = malloc(sizeof(int));
if (arr[i] == NULL)
{
return 0;
}
*arr[i] = i;
}
for (int i = 0; i < 3; i++)
{
printf("%d\n", *(arr[i]));
}
for (int i = 0; i < 3; i++)
{
free(arr[i]);
arr[i] = NULL;
}
//数组指针:指向数组的指针,是一个指针
//指针数组:存储指针的数组,是一个数组
return 0;
}
//***********************函数指针******************
//返回指针的函数:
//1.不要返回局部变量的地址,不安全,函数结束内存会释放。
//2.可以返回静态变量的地址,延长其声明周期
//3.可以返回动态内存分配的地址,因为不会自动释放
//
int* rePoint()
{
//static int num = 12;
int *res = malloc(sizeof(int));
memset(res, 0, 4);
return res;
}
int main()
{
int* res = rePoint();
printf("%d", *res);//能输出但是不安全,可能内存被别人占用而输出错误的值
}
版权声明:本文为Oliverzoo原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。