网站开发软件 d流量精灵
- 作者: 五速梦信息网
- 时间: 2026年03月21日 07:34
当前位置: 首页 > news >正文
网站开发软件 d,流量精灵,建筑模板多少钱一张,装修图库大全图片/*** file * author jUicE_g2R(qq:3406291309)————彬(bin-必应)* 通信与信息专业大二在读 * copyright 2023.10* COPYRIGHT 原创技术笔记#xff1a;转载需获得博主本人同意#xff0c;且需标明转载源* language C/C* IDE Base on Mic…/*** file * author jUicE_g2R(qq:3406291309)————彬(bin-必应)* 通信与信息专业大二在读 * copyright 2023.10* COPYRIGHT 原创技术笔记转载需获得博主本人同意且需标明转载源* language C/C* IDE Base on Microsoft Visual Studio 2022* state Corrected/jUicE_g2R的个人主页
前期回顾指针、取地址、解引用*、引用
最近帮别人改C语言程序才发现了自己对这部分还是理解不够深平时写C会忽略一些底层的东西比如指针、地址一类的东西记录一下。
1 错误示范
//错误示范
#include stdio.h
#include malloc.h
typedef struct {int id;char name[10];
} nodeN,pNode;
int main(void) {pNode ptr (pNode)malloc(sizeof(nodeN)); //node是一个结构体指针变量malloc为该指针指向的对象开辟了空间scanf_s(%s, ptr-name); //这样写绝对会报…处 这个文件 引发的异常: … 写入位置 … 时发生访问冲突。return 0;
} 2 先来了解一下点运算符 、 箭头运算符 与 取地址运算符 首先 p t r ptr ptr 是一个 指针变量 指针变量 指针变量。 typedef struct pNode 等同于 typedef int* pInt 是 对 指针类型名 指针类型名 指针类型名 的 重定义 重定义 重定义而不是定义了一个 名为 p N o d e pNode pNode 的 指针变量 指针变量 指针变量 pNode ptr (pNode)malloc(sizeof(nodeN)); 的替换写法为 nodeN* ptr (pNode)malloc(sizeof(nodeN)); 或 nodeN* ptr (nodeN)malloc(sizeof(nodeN)); 其次要知道 -箭头运算符 和 .点运算符 近似都是获取 类或结构体 类或结构体 类或结构体 成员 的 运算符 运算符 运算符 、 等等一类的这种通过 运算符 运算符 运算符 获取成员的方式叫做 访问 访问 访问 而 访问 访问 访问 的实质就是 获取到数据。 再者需要知道这些 运算符 运算符 运算符 的 优先级 优先级 优先级 括号运算符 括号运算符 括号运算符 点运算符 点运算符 点运算符 箭头运算符 箭头运算符 箭头运算符 取地址运算符 取地址运算符 取地址运算符 node.name、ptr-name 2-1 然后需要知道 点运算符 点运算符 点运算符 与 箭头运算符 箭头运算符 箭头运算符 的区别
区别点运算符箭头运算符含义成员选择对象成员选择指针使用形式对象.成员名对象指针-成员名返回值直接返回访问得到的值返回指向结构体成员的指针调用要求编译器知道结构体的定义不需要知道结构体的定义因为是指针无需知道具体定义只需要知道指着哪个就行【即知道被指对象的地址就可以了】适用性需要在使用 node.name 之前包含该结构体的头文件这样不太适用于多文件开发【更偏向用于单文件】无需【因为不需要知道定义】
简单说 点运算符 点运算符 点运算符 是 结构体变量 结构体变量 结构体变量 访问 其 成员 的 操作符 箭头运算符 箭头运算符 箭头运算符 是 结构体指针 结构体指针 结构体指针 访问 其 指向的成员变量 的 操作符
3 有如下两种修改方法
2-1 不使用 scanf_s
#define _CRT_SECURE_NO_WARNINGS //必须加在所有.h文件的前面使编译器不对 “没有使用安全函数scanf_s” 这种行为 进行报错
#include stdio.h
#include malloc.h
typedef struct {int id;char name[10];
} nodeN,*pNode;
int main(void) {pNode ptr (pNode)malloc(sizeof(nodeN));scanf(%s, ptr-name); return 0;
} _CRT_SECURE_NO_WARNINGS 我们鼠标箭头移至 _CRT_SECURE_NO_WARNINGS 这段右键选择 速览定义 速览定义 速览定义就可以看到vcruntime.h 文件的这一段
// See note on use of deprecate at the top of this file
#define _CRT_DEPRECATE_TEXT(_Text) __declspec(deprecated(_Text))#if defined _CRT_SECURE_NO_DEPRECATE !defined _CRT_SECURE_NO_WARNINGS#define _CRT_SECURE_NO_WARNINGS
#endif#ifndef _CRT_INSECURE_DEPRECATE#ifdef _CRT_SECURE_NO_WARNINGS#define _CRT_INSECURE_DEPRECATE(_Replacement)#else#define _CRT_INSECURE_DEPRECATE(_Replacement) _CRT_DEPRECATE_TEXT( \This function or variable may be unsafe. Consider using #_Replacement \ instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. \See online help for details.)#endif
#endif其实就相当于
#ifdef _CRT_SECURE_NO_WARNINGS
//TODO编译器不对安全函数进行检查
#else
//TODO编译器必须对安全函数的使用进行检查
#elseif2-2 使用 scanf_s 注意 安全函数的第三个参数不可少传入的是变量的字节大小可以用 s i z e o f ( ) 函数 sizeof()函数 sizeof()函数 获取也可以手动计算 #include stdio.h
#include malloc.h
#define NAMESIZE 10
typedef struct {int id;char name[NAMESIZE];
} nodeN,*pNode;
int main(void) {pNode ptr (pNode)malloc(sizeof(nodeN));scanf_s(%s, ptr-name, NAMESIZE); //这个 sizeof()函数 返回的值必须加上//scanf_s(%s, (ptr-name), NAMESIZE); //这样也是可以的(ptr-name)是一种无效操作return 0;
}4 进一步理解结构体指针
首先不得不说 地址即指针指针即地址 地址即指针指针即地址 地址即指针指针即地址
4-1 取地址运算符 首先取地址运算符 返回的结果一般认为是 地址 地址 地址实际上返回的就是一个指针因为指针变量的值就是地址值 其次scanf_s() 中 是否必要有 取值运算符 呢并非如此 因为 scanf_s()第二个参数就是 传的 地址值。 一种是不知道地址就要通过 去获取地址即 变量 变量 变量 去向左结合 来获得 变量的地址 变量的地址 变量的地址。 另一种 如果知道 变量的地址 变量的地址 变量的地址可以直接填入如直接填入 n a m e name name 这个地址。这一点下面的 仔细揣摩以下两个概念 仔细揣摩以下两个概念 仔细揣摩以下两个概念 会用的
4-2 数组名name
//C
#define NAMESIZE 10
char name[NAMESIZE];1、 n a m e name name 这个数组名 是一个指针常量 数组名 即为 数组首地址 n a m e name name 等价于 name[0] 数组名 是 数组 第一个元素 的 指针即 n a m e name name 指向 n a m e 数组 name数组 name数组 的 首元素
下面的例子足以说明 n a m e name name 这个数组名 就是一个地址
scanf_s(%s, name, NAMESIZE);//终端读入 NAMESIZE 字节大小的 char型 的 数据流存入到 name数组 里2、 n a m e i namei namei 等价于 a[i] n a m e i namei namei 指向 数组 第 i 个 元素
//C终端读入向 name数组 的第二个单元 写入 char型 数据
scanf_s(%c, name[1], NAMESIZE);
scanf_s(%c, name1, NAMESIZE);3、数组名取地址 name 是一种 无效 操作 n a m e name name 等于 name他们的值 都表示 数组首元素的地址
printf_s(%p\n, name[0]); //首元素的地址值 的 指标00D3F9B8
printf_s(%p\n, name); //输出数组首元素的地址00D3F9B8
printf_s(%p\n, name); //输出数组本身即首元素地址的地址00D3F9B8虽然两者值相同但是他们的 类型 是不相同的
区别namename定义指针常量一个指向指针常量的指针指针的指针类型 一级指针 一级指针 一级指针函数指针类型 二级指针 二级指针 二级指针在这里的类型charchar()一个指向返回值为 char型 的函数的指针
简单说name 指向 n a m e name name n a m e name name 指向 n a m e 数组 name数组 name数组 的 首元素。
4-3 进一步上升到 结构体指针 ptr
//C
#define NAMESIZE 10
typedef struct {int id;char name[NMAESIZE];
} nodeN,*pNode;
int main(void){pNode ptr (pNode)malloc(sizeof(nodeN));//结构体指针nodeN node;//结构体变量 1、可以把 一个结构体变量 想象成一个 集成了一种或多种类型 的 一维数组 类推先前的结论 n a m e name name 这个数组名 是一个指针常量则 p t r 结构体指针 ptr结构体指针 ptr结构体指针 n o d e 结构体名 node结构体名 node结构体名 p t r 指针 ptr指针 ptr指针 的值为 其 指向对象 指向对象 指向对象结构体的 首地址值或叫做 p t r 指针 ptr指针 ptr指针 指向 结构体的首地址 2、修改 和 只访问 结构体变量 结构体变量 结构体变量 中 非数组 成员
通过 scanf_s()终端从外部读入输入 值 算一种 修改赋值 参数的方式
通过 printf_s()终端写出到外部 值 算一种 只访问 参数的方式
//node.id实际上就是个变量 而不是 指针
scanf_s(%d, node.id, sizeof(node.id));
printf_s(%d, node.id, sizeof(node.id));3、修改 和 只访问 结构体指针 结构体指针 结构体指针 中 非数组 成员
//ptr-id箭头运算符 直接返回 ptr-id指针所指的 成员id的值而不会返回指针本身
scanf_s(%d, ptr-id, sizeof(ptr-id));
printf_s(%d, ptr-id, sizeof(ptr-id));
printf_s(%d, (*ptr).id, sizeof(ptr-id));( ∗ p t r ) . i d (*ptr).id (∗ptr).id 等于 p t r − i d ptr-id ptr−id 【 ( ∗ p t r ) . i d (*ptr).id (∗ptr).id 中 ( ∗ p t r ) (*ptr) (∗ptr) 由于有括号 p t r ptr ptr 先与 ∗ * ∗ 相与这步叫 解引用 解引用 解引用此时 ( ∗ p t r ) (*ptr) (∗ptr) 与 n o d e node node 等价】
4、修改 和 只访问 结构体指针 结构体指针 结构体指针 中 数组 成员 仔细揣摩以下两个概念 一个就是 在 2-1 提到了 箭头运算符 箭头运算符 箭头运算符 返回的是 指向结构体成员的指针 另一个就是 对象指针 − 成员 对象指针-成员 对象指针−成员 是 值 如果 成员 是 非数组 非数组 非数组这个 值 就是 对应成员的数据类型的 值
如果 成员 是 数组 数组 数组这个 值 是个 指针这个值 为 数组的首地址这样就好解释为什么是这种改法了
scanf_s(%s, ptr-name, NAMESIZE);//ptr-name 就是 结构体中name数组成员 的首地址
//scanf_s(%s, ptr-name, sizeof((*ptr).name));5、修改 和 只访问 结构体变量 结构体变量 结构体变量 中 数组 成员
同理 n o d e . n a m e node.name node.name 也可以获得 n a m e 指针 name指针 name指针 的值
scanf_s(%s, node.name, NAMESIZE);(ptr-name) 又是什么玩意 (ptr-name)是无效的操作可以不看这部分内容因为是个人观点不代表正确 ptr-name 是一个 地址值可以看成一个指针。
(ptr-name) 这就要涉及 指针的指针 了。前面说了取地址运算符 返回的结果一般认为是 地址 地址 地址实际上返回的就是一个指针
因为单纯的访问指针1 的话就只需要使用一级指针1 而操作修改指针的话就要使用到 二级指针2即(ptr-name) 就是指针的指针-(ptr-name)。
由于我们要通过 终端输入的方式 向 n a m e name name 这个结构体成员变量赋值实质上是在修改指针1就需要传入3 二级指针2来修改 一级指针1进而我们就可以通过这个指针2 来访问和修改 一级指针1 所指向的内存位置上的数据。
1 一级指针ptr-name 这个指针
2 二级指针1 的指针【或叫地址】
3 先以 一级指针 为例
void update(*a){a2;}
int main(void) {int a1;update(a); //更新整形变量 a 的值需要传入 a 的指针用 获取printf_s(%d, a);
}进一步 二级指针
void update(int** pp) {**pp 2;}int main(void) {int a 1;int p a; //p指向aupdate(p); //传入a的二级指针printf_s(%d, a);
}5 警告 C6011 取消对 NULL 指针 “ptr” 的引用 的解决办法
这个是在给 指针指向的对象 开辟了空间时即
//C
pNode ptr (pNode)malloc(sizeof(nodeN));//C
pNode p new node;的时候没有对 申请空间的时候可能会存在失败的情况 的极端情况进行处理。
解决办法
//C/C
while(!ptr){ //直至申请成功为止//TODO:上述代码
}jUicE_g2R的个人主页确定不点开看看
- 上一篇: 网站开发入门看什么动物大联盟微信小程序入口
- 下一篇: 网站开发软件成本网站官网域名要多少钱
相关文章
-
网站开发入门看什么动物大联盟微信小程序入口
网站开发入门看什么动物大联盟微信小程序入口
- 技术栈
- 2026年03月21日
-
网站开发入股合作分配比例wordpress 热门关键字
网站开发入股合作分配比例wordpress 热门关键字
- 技术栈
- 2026年03月21日
-
网站开发如何避免浏览器缓存的影响肇庆seo排名
网站开发如何避免浏览器缓存的影响肇庆seo排名
- 技术栈
- 2026年03月21日
-
网站开发软件成本网站官网域名要多少钱
网站开发软件成本网站官网域名要多少钱
- 技术栈
- 2026年03月21日
-
网站开发软件技术专业好吗wordpress 设置邮件
网站开发软件技术专业好吗wordpress 设置邮件
- 技术栈
- 2026年03月21日
-
网站开发软件平台有哪些wordpress的icon
网站开发软件平台有哪些wordpress的icon
- 技术栈
- 2026年03月21日






