#include <stdio.h>
#include <stdlib.h>
//说明指针和数组的关系
void fun()
{
//数组名代表整个数组,实际上他是一个地址
int arr[10] = { 1, 2, 3, 4, 5, 7, 6 };
//arr指向的是arr[0],所以数组名当做指针使用指向数组的第一个元素的首地址
printf("arr = %p,&arr[0] = %p\n", arr, &arr[0]);
int* p = arr;
//p现在也指向arr的第一个元素 是&arr[0]
printf("p = %p\n", p);
//arr有两重意思,第一重意思是指针,指向第一个元素,第二个是代表整个数组,sizeof得到的是整个数组的大小
//int* p = arr; 中的p只有指针的属性,不再代表整个数组
printf("sizeof(arr) = %d sizeof(p) = %d", sizeof(arr), sizeof(p));
//指针和指针不可以相加 int* p;int *q; p+q是错误的。
//arr和arr+1相差4个字节,是因为int类型的指针指向的是int数据,指针每加1个数值,实际上地址相加了一个int类型
printf("arr+1 = %p,arr = %p,\n", arr + 1,arr);
printf("p+1 = %p,p = %p,\n", p + 1, p);
//所有连续的内存空间都可以使用下标操作
p[1] = 20; //等价于arr[1] = 20;
printf("arr[1] = %d p[1] = %d\n", arr[1], p[1]);
//
//arr++;是错误的,数值名是指针常量,不可以改变他的指向。
//arr+1;这句话是对的,arr的指向没有改变,只改变了arr+1的结果
p++;
}
//手动申请内存,malloc
void fun1()
{
/*
int *p;
*p = 30;其中的p就是野指针
//野指针指指向一个已删除的对象或未申请访问受限内存区域的指针。与空指针不同,野指针无法通过简单地判断是否为 NULL 避免,而只能通过养成良好的编程习惯来尽力减少。对野指针进行操作很容易造成程序错误。
*/
int arr[10] = { 0 };
//申请内存空间malloc函数,参数是要申请的字节大小,返回值是void*,代表可以指向任何类型的内存空间
//(int*)是强制类型转化,把void*转行成int*
//malloc是在堆中申请内存,一堆沙子。理想状态下,堆是无限大的。
int* p = (int*)malloc(10*sizeof(int));//等价于int arr[10];
//p = arr;语法上可以,但修改p的指向之后会导致内存泄露
//如果指针是null说明是空指针,不指向任何一个位置
if (p == NULL)
{
printf("内存申请失败\n");
return 0;
}
*p = 20;
*(p + 1) = 30;
printf(" p = %d,p+1 = %d", *p,p[2]);
printf("p = %d", sizeof(p));
//malloc申请的内存必须释放,释放用free
//释放并不是说内存空间不存在,而是内存空间不再属于申请者管理,如果对于一个已经释放的内存空间操作,可能会出现意想不到的结果。
//所以说free之后,一定要对指针赋值成NULL
free(p);
p = NULL;
}
//指针和字符串的关系
void fun2()
{
//arr是局部变量,存在于栈区。
char arr[10] = "abcd";
//p是指针,指向某一个内存区域,指向“abcd”的内存区域,“abcd”放在只读常量区
char* p = "abcd";//const
//int* q = 10;错误
printf("arr = %p,p = %p\n",arr,p);
//*p = 'b';p指向的内存是只读的,通过p去修改只读的内存区域是不行的。
arr[1] = 'v';
}
int main()
{
//fun();
//fun1();
fun2();
return 0;
}
#include <stdlib.h>
//说明指针和数组的关系
void fun()
{
//数组名代表整个数组,实际上他是一个地址
int arr[10] = { 1, 2, 3, 4, 5, 7, 6 };
//arr指向的是arr[0],所以数组名当做指针使用指向数组的第一个元素的首地址
printf("arr = %p,&arr[0] = %p\n", arr, &arr[0]);
int* p = arr;
//p现在也指向arr的第一个元素 是&arr[0]
printf("p = %p\n", p);
//arr有两重意思,第一重意思是指针,指向第一个元素,第二个是代表整个数组,sizeof得到的是整个数组的大小
//int* p = arr; 中的p只有指针的属性,不再代表整个数组
printf("sizeof(arr) = %d sizeof(p) = %d", sizeof(arr), sizeof(p));
//指针和指针不可以相加 int* p;int *q; p+q是错误的。
//arr和arr+1相差4个字节,是因为int类型的指针指向的是int数据,指针每加1个数值,实际上地址相加了一个int类型
printf("arr+1 = %p,arr = %p,\n", arr + 1,arr);
printf("p+1 = %p,p = %p,\n", p + 1, p);
//所有连续的内存空间都可以使用下标操作
p[1] = 20; //等价于arr[1] = 20;
printf("arr[1] = %d p[1] = %d\n", arr[1], p[1]);
//
//arr++;是错误的,数值名是指针常量,不可以改变他的指向。
//arr+1;这句话是对的,arr的指向没有改变,只改变了arr+1的结果
p++;
}
//手动申请内存,malloc
void fun1()
{
/*
int *p;
*p = 30;其中的p就是野指针
//野指针指指向一个已删除的对象或未申请访问受限内存区域的指针。与空指针不同,野指针无法通过简单地判断是否为 NULL 避免,而只能通过养成良好的编程习惯来尽力减少。对野指针进行操作很容易造成程序错误。
*/
int arr[10] = { 0 };
//申请内存空间malloc函数,参数是要申请的字节大小,返回值是void*,代表可以指向任何类型的内存空间
//(int*)是强制类型转化,把void*转行成int*
//malloc是在堆中申请内存,一堆沙子。理想状态下,堆是无限大的。
int* p = (int*)malloc(10*sizeof(int));//等价于int arr[10];
//p = arr;语法上可以,但修改p的指向之后会导致内存泄露
//如果指针是null说明是空指针,不指向任何一个位置
if (p == NULL)
{
printf("内存申请失败\n");
return 0;
}
*p = 20;
*(p + 1) = 30;
printf(" p = %d,p+1 = %d", *p,p[2]);
printf("p = %d", sizeof(p));
//malloc申请的内存必须释放,释放用free
//释放并不是说内存空间不存在,而是内存空间不再属于申请者管理,如果对于一个已经释放的内存空间操作,可能会出现意想不到的结果。
//所以说free之后,一定要对指针赋值成NULL
free(p);
p = NULL;
}
//指针和字符串的关系
void fun2()
{
//arr是局部变量,存在于栈区。
char arr[10] = "abcd";
//p是指针,指向某一个内存区域,指向“abcd”的内存区域,“abcd”放在只读常量区
char* p = "abcd";//const
//int* q = 10;错误
printf("arr = %p,p = %p\n",arr,p);
//*p = 'b';p指向的内存是只读的,通过p去修改只读的内存区域是不行的。
arr[1] = 'v';
}
int main()
{
//fun();
//fun1();
fun2();
return 0;
}