关于指针的小知识

每个变量都有一个自己的地址,不论是 char ,int ,double,等,都是有地址的,并且是唯一的,只属于自己的。可以保存这个地址的变量就是指针。 

指针:用来储存变量的地址的一个变量(指针==地址)


1:交换两个数字的值;

void Swap_err1(int a,int b)
{
int tmp;
tmp = a;
a = b;
b = tmp;
}

如上的做法是错误的

原因是只交换了子函数中a,b变量的值,而父函数里面的a,b变量已经不是子函数里面的值了,两个a,b不是同一个,因为它们的地址不同。因此,我们需要通过指针来让父函数和子函数建立联系,然后通过解引用,来得到a,b的值,从而达到交换值的目的。


正确的写法如下:

void Swap_err1(int a,int b)
{
int tmp;
tmp = a;
a = b;
b = tmp;
}

void Charge(int *p1,int *p2)

{
int tmp;
tmp=*p1;
*p1=*p2;
*p2=tmp;
}


int main()
{
int a=10;
int b=20;
Charge(&a,&b);
  printf("%d,%d\n",a,b);
   return 0;

}

//重要   父函数调用子函数:子函数能修改i父函数中内容的前提是:1,传指针2,解引用

int Fun1(int a)
{
return ++a;
}


int main()
{
int a = 10;
int b = Fun1(a);
printf("%d,%d\n",a,b);//10,11


return 0;
}

在这个代码中,错误点在于父函数和子函数中的参数a已经不是同一个a。


2,在数组中,int *p=arr//指向数组的第一个格子。

int main()
{
int a = 10;
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
int *p = arr;int *p=arr       //指向数组的第一个格子。
*p = 10;                          //解引用arr[0]中的值改为10;
p++;//??                          //指针加1,就是加一个格子(也就书int  +4字节    double +8个字节等依次类推)
*p = 20;                         //解引用arr[1]中的值改为20;
printf("%d,%d\n",arr[0],arr[1]);
  
return 0;
}














<think>嗯,用户之前已经询问过关于指针的基本概念,现在又进一步问“关于指针知识点”。我需要判断他们到底需要哪些更深层次的信息。可能他们已经了解基础,现在想系统性地学习更多相关内容。 首先,回顾之前的对话,用户已经知道指针是存储内存地址变量,以及其特点,比如直接访问内存、高效性和灵活性。现在可能需要更详细的知识点,比如指针的操作、类型、常见错误,以及在不同语言中的应用。 接下来,用户可能对指针的使用场景感兴趣,比如动态内存分配、数组和指针的关系、函数指针等。另外,他们可能想了解指针在高级语言中的替代方案,比如C#中的引用类型或托管指针,以及智能指针的概念。 需要确保覆盖指针的基础知识点,如声明、初始化、解引用、运算,然后深入指针与数组、函数、动态内存的关系。同时,可能涉及常见错误,如空指针、野指针、内存泄漏,以及如何避免这些问题。 还要考虑用户可能的实际应用场景,比如在数据结构(链表、树)中的使用,或者多级指针的应用。此外,对比不同编程语言中的指针实现,可以满足用户扩展知识的需求。 最后,检查是否需要补充指针的高级主题,如函数指针的应用场景,多级指针的使用,以及现代C++中的智能指针机制。这些内容能帮助用户全面理解指针的各个方面,避免常见错误,并有效利用指针进行高效编程。</think>好的!我将分步骤介绍指针的核心知识点,帮助你系统理解这一概念。 --- ### 一、指针基础 1. **定义** 指针是**存储变量内存地址**的特殊变量。 例如: ```c int a = 10; // 定义整型变量a int *p = &a; // p指向a的地址(&a表示取a的地址) ``` 2. **声明与初始化** - 语法:`数据类型 *指针变量名;` ```c int *p; // 声明一个整型指针 char *c_ptr; // 声明一个字符指针 ``` - **必须初始化**:未初始化的指针可能指向非法内存(野指针)。 3. **解引用(Dereference)** 通过`*`访问指针指向地址的数据: ```c printf("%d", *p); // 输出a的值(10) *p = 20; // 修改a的值为20 ``` --- ### 二、指针与内存 1. **内存地址操作** - 指针支持算术运算(仅限加减): ```c int arr[3] = {1, 2, 3}; int *ptr = arr; // ptr指向数组首地址 ptr++; // 指向下一个元素(地址+sizeof(int)) ``` 2. **动态内存分配** - `malloc`/`free`:C语言中动态分配堆内存 ```c int *ptr = (int*)malloc(5 * sizeof(int)); // 分配5个int空间 free(ptr); // 释放内存 ``` - `new`/`delete`:C++中的动态内存管理 ```cpp int *ptr = new int[5]; delete[] ptr; ``` --- ### 三、指针类型与复杂用法 1. **指针类型** - 空指针(`NULL`/`nullptr`):表示指针未指向任何地址 ```c int *p = NULL; // C语言 int *p = nullptr; // C++11后推荐 ``` - 通用指针(`void*`):可指向任意类型,但需强制类型转换后才能使用 ```c void *vp = &a; int *ip = (int*)vp; ``` 2. **指针与数组** 数组名本质是指向首元素的指针: ```c int arr[3] = {1, 2, 3}; int *p = arr; // p指向arr[0] printf("%d", p[1]); // 输出arr[1]的值(2) ``` 3. **多级指针** 指向指针指针: ```c int a = 10; int *p = &a; int **pp = &p; // pp指向指针p的地址 printf("%d", **pp); // 输出10 ``` 4. **函数指针** 指向函数的指针,用于回调机制: ```c int add(int a, int b) { return a + b; } int (*func_ptr)(int, int) = add; // 定义函数指针 printf("%d", func_ptr(2, 3)); // 输出5 ``` --- ### 四、常见错误与规避 1. **野指针(Dangling Pointer)** - 原因:指针指向已释放的内存 - 规避:释放内存后置指针为`NULL` ```c free(ptr); ptr = NULL; // 防止后续误用 ``` 2. **内存泄漏(Memory Leak)** - 原因:动态分配的内存未释放 - 规避:确保每个`malloc`对应一个`free`,或使用智能指针(C++)。 3. **空指针解引用** - 原因:对未初始化的指针(`NULL`)进行解引用 - 规避:使用前检查指针有效性 ```c if (ptr != NULL) { *ptr = 10; } ``` --- ### 五、指针在不同语言中的替代方案 1. **C#** - 使用`引用类型`(类、数组)隐式管理指针 - 显式指针需在`unsafe`代码块中声明 ```csharp unsafe { int a = 10; int* p = &a; } ``` 2. **Java/Python** - 无显式指针,通过对象引用间接管理内存(JVM/Python解释器自动回收垃圾)。 3. **现代C++** - 智能指针(`unique_ptr`, `shared_ptr`)自动管理内存生命周期。 --- ### 六、应用场景 1. **数据结构**:链表、树、图的实现 2. **函数参数传递**:避免大对象复制(如传递结构体指针) 3. **硬件操作**:直接读写特定内存地址(嵌入式开发) --- 如果对某个知识点有疑问,可以具体提问!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值