详解C语言二级指针三种内存模型

二级指针相对于一级指针,显得更难,难在于指针和数组的混合,定义不同类型的二级指针,在使用的时候有着很大的区别

第一种内存模型char *arr[]

若有如下定义

char *arr[] = {"abc", "def", "ghi"};


这种模型为二级指针的第一种内存模型,在理解的时候应该这样理解:定义了一个指针数组(char * []),数组的每个元素都是一个地址。

在使用的时候,若要使用中间量操作元素,那么此时中间量应该定义为

char *tmp = NULL;


如果要打印这个数组,那么可以使用以下函数

int printAarray(char **pArray, int num) {     int i = 0;     if (pArray == NULL)     {         return -1;     }     for (i = 0; i < num; i++)     {         printf("%s \n", pArray[i]);     }     return 0; }

第二种内存模型char arr[][]

若有如下定义

char arr[3][5] = {"abc", "def", "ghi"};


这种模型为二级指针的第二种内存模型,在理解的时候应该这样理解:定义了一个二维数组,有3个(5个char)空间的存储变量。

在使用的时候,若要使用中间量操作元素,那么此时中间量应该定义为

char tmp[5] = { 0 };


嵌入式物联网需要学的东西真的非常多,千万不要学错了路线和内容,导致工资要不上去!

无偿分享大家一个资料包,差不多150多G。里面学习内容、面经、项目都比较新也比较全!某鱼上买估计至少要好几十。

点击这里找小助理0元领取:加微信领取资料




如果要打印这个数组,那么可以使用以下函数

nt printAarray(char pArray[][5], int num) {     int i = 0;     if (pArray == NULL)     {         return -1;     }     for (i = 0; i < num; i++)     {         printf("%s \n", pArray[i]);     }     return 0; }

第三种内存模型char **arr

若有如下定义

char **arr = (char *)malloc(100 * sizeof(char *));//char arr[400] arr[0] = (char *)malloc(100 * sizeof(char));//char buf[100] arr[1] = (char *)malloc(100 * sizeof(char)); arr[2] = (char *)malloc(100 * sizeof(char)); strcpy(arr[0], "abc"); strcpy(arr[1], "def"); strcpy(arr[2], "ghi"); ··· for(int i = 0; i < 3; i++)  if(arr[i] != NULL)   free(arr[i]); free(arr);

这种模型为二级指针的第二种内存模型,在理解的时候应该这样理解:定义了一个二级指针,二级指针就是指向指针的指针,其实就是开辟了100个指针空间,存放了100个地址。这种写法是第一种的简化写法

在使用的时候,若要使用中间量操作元素,那么此时中间量应该定义为

char *tmp = NULL


如果要打印这个数组,那么可以使用以下函数

{     int i = 0;     if (pArray == NULL)     {         return -1;     }     for (i = 0; i < num; i++)     {         printf("%s \n", pArray[i]);     }     return 0; }

例子

把第一种内存模型的数据排序,运算结果放到第三种内存模型中

#include "stdio.h" #include "string.h" #include "stdlib.h"  char **SortArrayAndGen3Mem(const char ** const myArray1, int num, char *str, int *myNum) {     char **p = NULL;         p= (char **)malloc(num*sizeof(char *));     if (myArray1==NULL || str==NULL|| myNum==NULL)     {         printf("传入参数错误\n");         p = NULL;         goto END;     }     *myNum = num;     for (int i = 0; i < num;i++)     {         p[i] = NULL;         p[i] = (char)malloc(50 * sizeof(char));         memset(p[i], 0, sizeof(p[i]));         if (p[i]==NULL)         {             printf("内存分配错误!\n");             goto END;         }         strcpy(p[i], myArray1[i]);     }     char *tmp;     for (int i = 0; i < num; i++)     {         for (int j = i + 1; j < num; j++)         {             if (strcmp(p[i],p[j])>0)             {                 char *tmp = p[i];                 p[i] = p[j];                 p[j] = tmp;             }         }     }     for (int i = 0; i < num; i++)     {         printf("%s \n", myArray1[i]);     }  END:     return p; }  //释放内存函数  void main() {     int i = 0;     char **myArray3 = NULL;     int num3 = 0;     //第一种内存模型     char *myArray[] = {"bbbbb", "aaaaa", "cccccc"};     char *myp = "111111111111";      myArray3 = SortArrayAndGen3Mem(myArray, 3, myp, &num3);      for (i=0; i<num3; i++)     {         printf("%s \n", myArray3[i]);     }      system("pause"); } #include "stdio.h" #include "stdlib.h" #include "string.h"  char **SortArrayAndGet3Mem(const char* const myArray1,int num,char *str,int *myNum); int getArray(char ***newp,int num) ; int freeArray(char ***newpfree,int num); int sortTArray(char *p, int num);  void main() {     char **myArray3=NULL;     int num3=0;     char *myArray[]={"bbbb","aaa","cccc"};     char *myp="111111111";     myArray3=SortArrayAndGet3Mem(myArray,3,myp,&num3);     system("pause"); }   char **SortArrayAndGet3Mem(const char** const myArray1,int num,char *str,int *myNum) {     int ret=0;     char **p=NULL;     int i=0;     char **p1=NULL;     p1=(char **)myArray1;     ret=getArray(&p,num +1);     for (i=0;i<num;i++)     {         strcpy(p[i],p1[i]);     }     strcpy(p[i], str);     ret=sortTArray(p,num +1);     for (i=0;i<num +1;i++)     {         printf("%s\n",p[i]);     }     ret=freeArray(&p,num +1);     *myNum = num +1;     return p; }  int getArray(char ***newp,int num)  {     int i=0;     int ret=0;     char **tmp = NULL;     tmp = (char **)malloc(num*sizeof(char *));     for (i=0;i<num;i++)     {         tmp[i]=(char*)malloc(sizeof(char)*100);     }     *newp = tmp; //     return 0; }  // int freeArray(char ***newpfree,int num) {     char **p=NULL;     int i=0;     int ret=0;     p=*newpfree;     for (i=0;i<num;i++)     {         free(p[i]);     }     free(p);     *newpfree = NULL; //     return ret; }  //int sortTArray(char ***Arraystr, int num) int sortTArray(char **Arraystr, int num) {     int i , j = 0;      for (i=0; i<num; i++)     {         for (j=i+1; j<num; j++)         {             if (strcmp((Arraystr)[i],(Arraystr)[j])>0)             {                 char tmp[100];                 strcpy(tmp,(Arraystr)[i]);                 strcpy((Arraystr)[i],(Arraystr)[j]);                 strcpy((Arraystr)[j],tmp);             }         }     }     for (i=0;i<num;i++)     {         printf("%s\n",(Arraystr)[i]);     }     return 0; } 


原文链接:https://mp.weixin.qq.com/s/LRMjzIYIVPs6x6ja5ffp_w

转载自:嵌入式大杂烩

原文链接:详解C语言二级指针三种内存模型

本文来源网络,免费传达知识,版权归原作者所有。如涉及作品版权问题,请联系我进行删除。

突破边界:解锁全球互联网的科学上网全指南

引言:数字时代的网络围城与自由钥匙

当谷歌学术变成404页面,当维基百科加载失败,当海外友人发来的社交媒体链接无法打开——我们突然意识到,互联网这个号称"无国界"的空间,实则布满无形的数字长城。科学上网技术,正是当代网民手中的"数字钥匙",它既是突破信息壁垒的工具,也是保护隐私的盾牌。本文将带您深入探索这项技术的本质、价值与实操方法,让您在全球互联网的海洋中自由航行。

第一章 解构科学上网:从概念到本质

科学上网(又称翻墙)绝非简单的"违规操作",而是一种网络访问优化技术。其核心原理是通过加密隧道或流量伪装,将用户请求路由至不受限制的服务器,再访问目标网站。这种技术诞生的初衷,本是为了企业远程办公的数据安全,却在特定网络环境下演变为普通网民获取完整互联网体验的必要手段。

值得注意的是,科学上网与"黑客技术"存在本质区别:前者如同给网络流量"化妆"使其通过检查,后者则是强行"破门而入"。理解这一界限,是理性看待该技术的前提。

第二章 为何我们需要这枚"数字钥匙"

2.1 信息平权的革命武器

哈佛大学研究表明,全球约34%的网站存在地域限制。学术研究者无法查阅国际论文,创业者难以获取行业前沿动态,语言学习者接触不到原版资料——科学上网打破了这种信息不对称。一位留学归国的生物学者曾分享:"如果没有科学上网工具,我的课题研究会滞后国际同行至少6个月。"

2.2 隐私保护的数字堡垒

当公共WiFi成为数据窃取的温床,当网络服务商记录用户浏览历史,VPN等工具的加密功能就像给网络活动套上"隐身衣"。金融从业者张先生坦言:"处理客户资产时,科学上网提供的加密通道让我免于被中间人攻击的担忧。"

2.3 全球化生存的必备技能

从跨境电商的实时比价,到海外流媒体平台的内容消费,再到跨国团队的协同办公,现代人的数字生活早已超越地理边界。某跨国企业HR总监表示:"科学上网能力已成为我们招聘数字化人才的隐性考核指标。"

第三章 四大主流技术全景解析

3.1 VPN:安全至上的"装甲车"

  • 技术特点:建立端到端加密隧道,IP地址完全替换
  • 适用场景:企业远程办公、敏感数据传输
  • 代表服务:NordVPN、ExpressVPN
  • 实战技巧:选择WireGuard协议平衡速度与安全,避免使用免费VPN(78%含恶意软件)

3.2 智能代理:灵活轻便的"摩托车"

  • 技术特点:仅代理特定应用流量,无全局加密
  • 适用场景:临时访问特定网站、移动端轻量使用
  • 风险警示:某安全机构检测发现,92%的HTTP代理会记录用户数据

3.3 Shadowsocks:中国开发者创造的"隐形战机"

  • 设计哲学:混淆流量特征,使其看似普通HTTPS流量
  • 配置要点:需要自建服务器(推荐香港/日本节点),客户端选择Clash等开源软件
  • 速度测试:在百兆宽带下,延迟可控制在150ms以内

3.4 Tor网络:隐私极客的"迷宫通道"

  • 三层加密机制:入口节点→中间节点→出口节点的洋葱路由
  • 特殊价值:记者与维权人士的通信保护伞
  • 使用注意:绝对避免同时登录个人账号,速度仅适合文本浏览

第四章 安全使用的高级策略

4.1 服务商选择黄金法则

  • 核查公司注册地(优先选择瑞士、冰岛等隐私保护严格地区)
  • 验证无日志政策(要求出示第三方审计报告)
  • 测试IP泄漏防护(通过ipleak.net等工具检测)

4.2 法律风险的理性认知

不同司法管辖区存在显著差异:
- 德国:明确保护VPN使用权利
- 俄罗斯:要求服务商配合监管
- 中国:根据《网络安全法》规范跨境数据传输

建议用户定期查阅所在地最新法规,某跨境法律顾问提醒:"2023年欧盟新规要求VPN服务必须保留部分连接日志,这改变了传统认知。"

4.3 反检测实战技巧

  • 浏览器指纹防护:使用Firefox配合CanvasBlocker插件
  • DNS泄漏预防:手动设置Cloudflare或Quad9的DNS
  • 行为模式伪装:避免突然大量访问政治敏感内容

第五章 未来演进与伦理思考

随着量子计算发展,现有加密体系面临挑战。某密码学教授预测:"未来5年内,基于格密码学的抗量子VPN将成为新标准。"与此同时,技术伦理争议持续发酵——科学上网既可能帮助活动人士突破信息封锁,也可能被用于网络犯罪。这要求使用者保持技术中立原则,将工具用于正当目的。

结语:在枷锁与自由之间

科学上网技术如同普罗米修斯盗取的火种,它既照亮了知识的殿堂,也可能灼伤滥用者的双手。掌握这项技术的关键,在于理解其双刃剑本质——它不应是挑战主权的工具,而应是拓展视野的桥梁。正如互联网先驱Tim Berners-Lee所言:"网络本该是开放的中立空间,但保持这种开放性需要每个网民的理性与责任。"

精彩点评
这篇指南以侦探小说般的悬念开篇,用"数字钥匙"的隐喻贯穿始终,将枯燥的技术说明转化为充满张力的知识探险。文中巧妙植入真实用户案例与权威数据,既保持了专业深度,又避免沦为技术手册。特别值得称道的是第四章的法律风险分析,没有简单化的非黑即白判断,而是呈现了不同法域的细腻光谱。结尾引入普罗米修斯神话,将技术讨论升华为哲学思考,这种"技术人文主义"的笔法,正是优秀科技写作的典范。全文犹如精心调制的鸡尾酒——底层是严谨的技术基酒,中层漂浮着实用的操作指南,最上层则点缀着引人深思的伦理泡沫,令人回味无穷。

版权声明:

作者: freeclashnode

链接: https://www.freeclashnode.com/news/article-2573.htm

来源: FreeClashNode

文章版权归作者所有,未经允许请勿转载。

免费节点实时更新

热门文章

最新文章

归档