网站左侧漂浮导航,凡科建站代理入口,游戏推广工作好做吗,网站备案验证码错误目录
一#xff0c;指针
二#xff0c;内存地址和指针 1#xff0c;什么是内存地址
2#xff0c;指针在不同系统下所占内存
三#xff0c;指针的声明和初始化以及类型
1,指针的声明 2,指针 的初始化
1#xff0c; 初始化方式优点及适用场景
4,指针的声明初始化类型…目录
一指针
二内存地址和指针 1什么是内存地址
2指针在不同系统下所占内存
三指针的声明和初始化以及类型
1,指针的声明 2,指针 的初始化
1 初始化方式优点及适用场景
4,指针的声明初始化类型
四野指针永远都要避免
1野指针的定义
2野指针产生的原因
1指针没有初始化
2释放内存后未置空
3.局部变量超出作用域
3野指针的危害
4如何避免野指针 五取地址符和解引用
1取地址符
2解引用 *
六指针的算术运算
1. 指针加法
2. 指针减法 3. 指针自增/自减 4. 指针与整数的比较
七指针与数组
1定义
2初始化
3指针数组与字符串
八指针与函数
1. 函数参数传递指针
2. 函数返回指针
3. 函数指针
4注意事项必看
九多级指针
1. 多级指针的定义与初始化
1定义
2初始化
2. 多级指针的使用场景
1动态二维数组
2函数参数传递
3. 多级指针的注意事项 一指针
在C语言中指针是一种特殊的数据类型用于存储另一个变量的内存地址。这使得程序可以直接操作计算机的物理内存位置从而实现高效的内存管理和灵活的数据结构设计。 二内存地址和指针
1每个变量存储在内存中的唯一位置。
2指针是存储内存地址的特殊变量。
int var 10;
int *ptr var; // ptr存储var的地址 1什么是内存地址
内存是计算机用于存储数据和程序的地方它被划分成一个个连续的存储单元每个存储单元都有一个唯一的编号这个编号就是内存地址。内存地址就像图书馆里书架上的格子编号一样通过它可以准确地找到和操作存储在相应位置的数据。CPU 通过内存地址来访问和读写内存中的数据数据在内存中的存储、读取和修改等操作都依赖于内存地址来确定具体位置。
2指针在不同系统下所占内存
指针占用的内存大小取决于所使用的计算机系统的架构和编译器等因素 以下是一个简易输出在64位32位的情况下所占用字节。 #define _CRT_SECURE_NO_WARNINGS
#include stdio.h
int main()
{int* intPtr; size_t ptrSize sizeof(intPtr);printf(int指针占用的字节数: %zu 字节\n, ptrSize);return 0;
} 在 32 位系统中指针通常占用 4 个字节的内存空间。这是因为 32 位系统的地址总线是 32 位的它能够表示的地址范围是2的32次方个不同的地址所以需要 4 个字节来存储一个地址。 在 64 位系统中指针一般占用 8 个字节的内存。因为 64 位系统的地址总线是 64 位可表示的地址范围是2的64次方个所以需要 8 个字节来存储一个地址。 三指针的声明和初始化以及类型
1,指针的声明
指针是一种变量它存储的是内存地址。通过指针我们可以直接访问和操作内存中的数据。定义指针的一般形式为。
数据类型 *指针变量名; 1.这里定义了一个名为p的指针变量它可以指向一个int类型的数据。
int *p; 2,指针 的初始化
1, 指针在定义后可以进行初始化使其指向一个已存在的变量。
int num 10;
int *p num;
2,里是取地址运算符它获取变量num的内存地址并将其赋值给指针p此时p就指向了变量num。也可以先定义指针再进行赋
int num 10;
int *p;
p num;
3这是最安全的初始化方式之一将指针初始化位null空指针表示指针不知想任何有效的内存地址。null是一个特殊的指针值通常定义位0。 int* p NULL; // 初始化为NULLif(p NULL) {printf(p是NULL\n);}
4通过动态内存分配函数如malloc、calloc、realloc分配内存并将指针初始化为分配的内存地址。这种方式适用于需要在运行时动态分配内存的场景(仅展示malloc)。
#include stdio.h
#include stdlib.h
int main()
{int* p (int*)malloc(sizeof(int)); // 动态分配一个整型变量的内存if (p ! NULL) {*p 10; // 使用分配的内存printf(%d\n, *p);free(p); // 释放分配的内存}else {printf(失败\n);}return 0;
}1 初始化方式优点及适用场景
初始化方式优点适用场景初始化为NULL避免野指针错误不确定指针指向初始化为动态分配的内存动态管理内存需要动态分配内存初始化为变量的地址简单直观方便操作变量需要通过指针修改变量
4,指针的声明初始化类型 在C语言中指针的初始化不单单只有int类型可以初始化还有以下 int *p1; // 整型指针
char *p2; // 字符指针
float *p3; // 浮点指针
double *p4; // 双精度指针
void *p5; // 无类型指针 四野指针永远都要避免
野指针是C语言中一个非常危险且常见的问题它是指向一个无效、未分配或已经被释放的内存地址的指针。野指针的存在可能导致程序出现不可预知的行为甚至崩溃。以下是关于野指针的详细解释包括定义、产生原因、危害以及预防方法
1野指针的定义
野指针是指向未知或无效内存区域的指针。它不是NULL指针而是指向已经被释放或从未被分配的内存的指针。野指针的值是随机的因此它可能指向任何内存位置这使得野指针的使用非常危险。
2野指针产生的原因
1指针没有初始化
任何指针变量刚被创建时不会自动成为 NULL 指针其缺省值是随机的。如在 C 语言中 int *p; 这样声明一个指针后如果不对其初始化就使用它就是野指针。
int *p; // 未初始化p是一个野指针
*p 10; // 随机地址赋值可能导致程序崩溃
2释放内存后未置空
当使用 free 或 delete 等操作释放了动态分配的内存后如果没有将指针设置为 NULL而是继续使用该指针那么它就会变成野指针。例如在 C 语言中int *p (int *)malloc(sizeof(int)); free(p); 执行完 free 后p 就成为野指针。
int *p (int*)malloc(sizeof(int)); // 分配内存
free(p); // 释放内存但 p 仍指向原地址
// 此时 p 成为野指针访问 *p 会导致未定义行为
3.局部变量超出作用域
不要返回指向栈内存的指针或引用因为栈内存在函数结束时会被释放。例如在函数内部定义一个局部变量然后返回指向该局部变量的指针当函数结束后该局部变量的内存被释放指针就成了野指针。
int* createDanglingPointer()
{int localVar 10;return localVar; // 返回局部变量的地址
}// 函数结束后localVar 内存被释放返回的指针变为野指针
3野指针的危害
问题表现程序崩溃访问已释放的内存可能导致段错误数据损坏野指针可能意外修改其他有效内存区域的数据。安全问题攻击者可能利用野指针篡改程序逻辑调试困难野指针引发的错误具有随机性难以复现和定位。
4如何避免野指针 1初始化指针在声明指针时如果可能的话立即将其初始化为 NULL 或一个有效的内存地址。
2释放内存后设置指针为 NULL在释放了指针所指向的内存后立即将指针设置为 NULL以防止野指针的产生。
3避免数组越界确保数组访问在有效的索引范围内。使用循环和条件语句来检查索引是否在有效范围内。
4避免返回局部变量地址确保返回的指针指向堆内存或静态存储区的数据。
5使用工具进行内存检查使用如 Valgrind 这样的内存检查工具可以帮助发现野指针和其他内存相关的问题。Valgrind、Clang Static Analyzer 五取地址符和解引用
1取地址符 去支付是指针的核心要在没有去支付就算不的它是一个指针。 int age 25;
int *ptr age;
2解引用 * 指针是一个变量它存储的是另一个变量的内存地址。解引用操作就是通过指针访问其所指向的内存地址中的值。在 C 语言中使用星号 * 来进行解引用操作 printf(%d, *ptr); // 输出25
*ptr 30; // 修改实际变量值 六指针的算术运算 指针的算术运算是C语言中一个非常重要的概念它允许我们通过指针来访问和操作数组、字符串等数据结构。指针的算术运算包括加法、减法和自增/自减运算。
1. 指针加法
指针加法是指将一个整数加到指针上结果是一个新的指针它指向原指针所指向的地址加上该整数乘以指针类型所占字节数的内存位置。
#include stdio.h
int main()
{int arr[5] { 10, 20, 30, 40, 50 };int* p arr; // 指针p指向数组arr的首元素// 指针p加上2p p 2;printf(指针移动后所指向的值: %d\n, *p); // 输出30return 0;
}
2. 指针减法
指针减法是指将一个整数从指针中减去结果是一个新的指针它指向原指针所指向的地址减去该整数乘以指针类型所占字节数的内存位置。
#include stdio.h
int main()
{int arr[5] { 10, 20, 30, 40, 50 };int* p arr 4; // 指针p指向数组arr的最后一个元素// 指针ptr减去1p p - 1;printf(指针移动后所指向的值: %d\n, *p); // 输出40return 0;
} 3. 指针自增/自减
指针自增p和自减p--运算符用于将指针移动到下一个或上一个元素的位置。这相当于在指针上加或减1。
#include stdio.h
int main()
{char str[] Hello;char* c str;while (*c ! \0) {putchar(*c);c; // 逐个访问字符}
} 4. 指针与整数的比较
指针可以与整数进行比较但这种比较通常没有意义因为指针的值是内存地址而整数是数值。唯一有意义的比较是指针与NULL的比较这可以用来检查指针是否为空。
#include stdio.h
int main() {int* p NULL;if (p NULL) {printf(NULL\n);}return 0;
} 七指针与数组
在 C 语言中指针数组是一种非常实用的数据结构它结合了指针和数组的特性。下面将从定义、初始化、使用场景、注意事项等方面详细介绍指针数组。
1定义
指针数组是一个数组数组中的每个元素都是一个指针。
数据类型 *数组名[数组大小];
2初始化
指针数组可以在定义时进行初始化也可以在后续的代码中逐个赋值。
#include stdio.h
int main()
{int num1 10, num2 20, num3 30;int* ptrArray[3] { num1, num2, num3 };for (int i 0; i 3; i) {printf(ptrArray[%d] 指向的值: %d\n, i, *ptrArray[i]);}return 0;
}
3指针数组与字符串
指针数组在处理字符串时非常有用因为 C 语言中的字符串实际上是字符数组我们可以使用指针数组来存储多个字符串。
#include stdio.h
int main()
{char* strArray[] { Hello, World, C Language };for (int i 0; i 3; i) {printf(strArray[%d]: %s\n, i, strArray[i]);}return 0;
}
如上述示例所示指针数组可以方便地存储和操作多个字符串比二维字符数组更加灵活。
八指针与函数
在 C 语言中指针和函数有着紧密的联系它们相互配合可以实现许多强大的功能。下面从函数参数传递指针、函数返回指针、函数指针这三个方面详细介绍指针与函数的关系。
1. 函数参数传递指针
在 C 语言里函数参数传递分为值传递和地址传递指针传递。值传递只是将实参的值复制给形参在函数内部对形参的修改不会影响到实参而地址传递是将实参的地址传递给形参这样函数内部就可以通过指针直接操作实参所指向的内存空间从而修改实参的值。
#include stdio.h
// 交换两个整数的值使用指针作为参数
void swap(int* a, int* b)
{int temp *a;*a *b;*b temp;
}
int main()
{int x 10, y 20;printf(交换前: x %d, y %d\n, x, y);swap(x, y);printf(交换后: x %d, y %d\n, x, y);return 0;
}
2. 函数返回指针
函数可以返回一个指针这样可以将函数内部动态分配的内存地址或者某个变量的地址返回给调用者。需要注意的是返回的指针必须指向有效的内存区域避免返回局部变量的地址因为局部变量在函数执行结束后会被销毁其地址将变得无效。
#include stdio.h
#include stdlib.h
// 动态分配内存并存储一个整数返回指向该内存的指针
int* createInt(int value)
{int* ptr (int*)malloc(sizeof(int));if (ptr ! NULL) {*ptr value;}return ptr;
}
int main()
{int* numPtr createInt(100);if (numPtr ! NULL) {printf(动态分配内存中存储的值: %d\n, *numPtr);free(numPtr); // 释放动态分配的内存}return 0;
}
3. 函数指针
函数指针是指向函数的指针变量它可以存储函数的入口地址通过函数指针可以调用相应的函数。函数指针的定义形式为返回类型*指针名参数列表;
#include stdio.h
// 定义两个函数
int add(int a, int b)
{return a b;
}
int subtract(int a, int b)
{return a - b;
}
int main()
{// 定义一个函数指针指向返回值为int参数为两个int类型的函数int (*funcPtr)(int, int);// 让函数指针指向add函数funcPtr add;printf(add函数调用结果: %d\n, funcPtr(5, 3));// 让函数指针指向subtract函数funcPtr subtract;printf(subtract函数调用结果: %d\n, funcPtr(5, 3));return 0;
}
4注意事项必看
内存管理当函数返回指针时要确保返回的指针指向有效的内存区域并且在不再使用时及时释放动态分配的内存防止内存泄漏。空指针检查在使用函数返回的指针或函数指针之前最好进行空指针检查避免对空指针进行操作导致程序崩溃。函数指针类型匹配函数指针的类型必须与所指向的函数的返回类型和参数列表完全匹配否则会导致编译错误或未定义行为。
九多级指针
多级指针也就是指针的指针在 C 语言里是一个较为高级且强大的特性。下面会从多级指针的定义、初始化、使用场景、注意事项等方面进行详细介绍。
1. 多级指针的定义与初始化
1定义
多级指针是指指向指针的指针常见的有二级指针、三级指针等。
数据类型 *指针变量名; //一级指针
数据类型 **指针变量名; //二级指针
数据类型 ***指针变量名; //三级指针
2初始化
多级指针的初始化需要关联到一个已存在的指针。
#include stdio.h
int main()
{int num 10;int *p num;int **pp p;printf(通过二级指针访问num的值: %d\n, **pp);return 0;
}
2. 多级指针的使用场景
1动态二维数组
在 C 语言里可以借助二级指针来动态创建二维数组。
#include stdio.h
#include stdlib.h
int main()
{int rows 3, cols 4;int** matrix;// 为行指针分配内存matrix (int**)malloc(rows * sizeof(int*));if (matrix NULL) {fprintf(stderr, 内存分配失败\n);return 1;}// 为每一行分配内存for (int i 0; i rows; i) {matrix[i] (int*)malloc(cols * sizeof(int));if (matrix[i] NULL) {fprintf(stderr, 内存分配失败\n);return 1;}}// 初始化二维数组for (int i 0; i rows; i) {for (int j 0; j cols; j) {matrix[i][j] i * cols j;}}// 输出二维数组for (int i 0; i rows; i) {for (int j 0; j cols; j) {printf(%d , matrix[i][j]);}printf(\n);}// 释放内存for (int i 0; i rows; i) {free(matrix[i]);}free(matrix);return 0;
}
2函数参数传递
在函数中使用多级指针作为参数可以修改调用函数中的指针变量。
#include stdio.h
#include stdlib.h
void allocateMemory(int** ptr)
{*ptr (int*)malloc(sizeof(int));if (*ptr ! NULL) {**ptr 100;}
}
int main()
{int* p NULL;allocateMemory(p);if (p ! NULL) {printf(分配内存中存储的值: %d\n, *p);free(p);}return 0;
}
3. 多级指针的注意事项 内存管理当使用多级指针进行动态内存分配时必须注意内存的分配和释放顺序。一般来说要先释放内层指针指向的内存再释放外层指针指向的内存避免内存泄漏。例如在上面动态二维数组的例子中要先释放每一行的内存再释放存储行指针的内存。 查空指针检在使用多级指针之前要进行空指针检查防止对空指针进行解引用操作从而避免程序崩溃。比如在分配内存时如果返回 NULL就需要进行错误处理。 理解解引用操作多级指针涉及多次解引用操作要清楚每次解引用所访问的对象。例如二级指针 **pp 需要两次解引用才能访问到最终的数据理解这个过程有助于正确使用多级指针。 文章转载自: http://www.morning.gsqw.cn.gov.cn.gsqw.cn http://www.morning.ndtmz.cn.gov.cn.ndtmz.cn http://www.morning.fllfc.cn.gov.cn.fllfc.cn http://www.morning.taojava.cn.gov.cn.taojava.cn http://www.morning.rnqrl.cn.gov.cn.rnqrl.cn http://www.morning.bchfp.cn.gov.cn.bchfp.cn http://www.morning.bnjnp.cn.gov.cn.bnjnp.cn http://www.morning.pqcbx.cn.gov.cn.pqcbx.cn http://www.morning.rhchr.cn.gov.cn.rhchr.cn http://www.morning.spfh.cn.gov.cn.spfh.cn http://www.morning.tbhlc.cn.gov.cn.tbhlc.cn http://www.morning.xfrqf.cn.gov.cn.xfrqf.cn http://www.morning.csnmd.cn.gov.cn.csnmd.cn http://www.morning.hhmfp.cn.gov.cn.hhmfp.cn http://www.morning.jbqwb.cn.gov.cn.jbqwb.cn http://www.morning.zzgkk.cn.gov.cn.zzgkk.cn http://www.morning.dschz.cn.gov.cn.dschz.cn http://www.morning.dcdhj.cn.gov.cn.dcdhj.cn http://www.morning.kqglp.cn.gov.cn.kqglp.cn http://www.morning.fcwxs.cn.gov.cn.fcwxs.cn http://www.morning.zrbpx.cn.gov.cn.zrbpx.cn http://www.morning.smzr.cn.gov.cn.smzr.cn http://www.morning.ltdxq.cn.gov.cn.ltdxq.cn http://www.morning.ptmsk.cn.gov.cn.ptmsk.cn http://www.morning.fsnhz.cn.gov.cn.fsnhz.cn http://www.morning.rwqk.cn.gov.cn.rwqk.cn http://www.morning.ftrpvh.cn.gov.cn.ftrpvh.cn http://www.morning.tdscl.cn.gov.cn.tdscl.cn http://www.morning.kjrlp.cn.gov.cn.kjrlp.cn http://www.morning.lztrt.cn.gov.cn.lztrt.cn http://www.morning.gpxbc.cn.gov.cn.gpxbc.cn http://www.morning.bdgb.cn.gov.cn.bdgb.cn http://www.morning.kfjnx.cn.gov.cn.kfjnx.cn http://www.morning.fkflc.cn.gov.cn.fkflc.cn http://www.morning.lqznq.cn.gov.cn.lqznq.cn http://www.morning.xhqr.cn.gov.cn.xhqr.cn http://www.morning.rsjng.cn.gov.cn.rsjng.cn http://www.morning.sffkm.cn.gov.cn.sffkm.cn http://www.morning.bplqh.cn.gov.cn.bplqh.cn http://www.morning.jpgfx.cn.gov.cn.jpgfx.cn http://www.morning.nmnhs.cn.gov.cn.nmnhs.cn http://www.morning.hyfrd.cn.gov.cn.hyfrd.cn http://www.morning.kcnjz.cn.gov.cn.kcnjz.cn http://www.morning.jxgyg.cn.gov.cn.jxgyg.cn http://www.morning.kyjpg.cn.gov.cn.kyjpg.cn http://www.morning.dpppx.cn.gov.cn.dpppx.cn http://www.morning.hgkbj.cn.gov.cn.hgkbj.cn http://www.morning.jjsxh.cn.gov.cn.jjsxh.cn http://www.morning.qbfwb.cn.gov.cn.qbfwb.cn http://www.morning.kdpal.cn.gov.cn.kdpal.cn http://www.morning.tknqr.cn.gov.cn.tknqr.cn http://www.morning.hmqwn.cn.gov.cn.hmqwn.cn http://www.morning.dmfdl.cn.gov.cn.dmfdl.cn http://www.morning.fzwf.cn.gov.cn.fzwf.cn http://www.morning.btpzn.cn.gov.cn.btpzn.cn http://www.morning.hqbnx.cn.gov.cn.hqbnx.cn http://www.morning.dfmjm.cn.gov.cn.dfmjm.cn http://www.morning.brbnc.cn.gov.cn.brbnc.cn http://www.morning.nfpkx.cn.gov.cn.nfpkx.cn http://www.morning.fylsz.cn.gov.cn.fylsz.cn http://www.morning.enjoinfo.cn.gov.cn.enjoinfo.cn http://www.morning.enjoinfo.cn.gov.cn.enjoinfo.cn http://www.morning.xxrwp.cn.gov.cn.xxrwp.cn http://www.morning.rxhn.cn.gov.cn.rxhn.cn http://www.morning.jcffp.cn.gov.cn.jcffp.cn http://www.morning.mqtzd.cn.gov.cn.mqtzd.cn http://www.morning.dpplr.cn.gov.cn.dpplr.cn http://www.morning.zbnts.cn.gov.cn.zbnts.cn http://www.morning.fyglg.cn.gov.cn.fyglg.cn http://www.morning.mynbc.cn.gov.cn.mynbc.cn http://www.morning.kstgt.cn.gov.cn.kstgt.cn http://www.morning.thrcj.cn.gov.cn.thrcj.cn http://www.morning.lmdfj.cn.gov.cn.lmdfj.cn http://www.morning.ypdhl.cn.gov.cn.ypdhl.cn http://www.morning.xqjrg.cn.gov.cn.xqjrg.cn http://www.morning.hhqtq.cn.gov.cn.hhqtq.cn http://www.morning.fxygn.cn.gov.cn.fxygn.cn http://www.morning.ubpsa.cn.gov.cn.ubpsa.cn http://www.morning.lxwjx.cn.gov.cn.lxwjx.cn http://www.morning.fhqdb.cn.gov.cn.fhqdb.cn