const char * 的终结贴(看完无需其他任何文章,从此不再蛋疼)

2023-12-05 09:58

本文主要是介绍const char * 的终结贴(看完无需其他任何文章,从此不再蛋疼),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

我之前也是以为我对const char *ptr 这种形式的写法是掌握了的,真的,不就是说一个指针是不可改变的吗?

 

那么问题就来了,到底是ptr指针本身不能改变,还是ptr执行的值不能改变呢?

 

从网上的资料上看,有如下的解释:

 

Bjarne在他的The C++ Programming Language里面给出过一个助记的方法: 
把一个声明从右向左读。 

char  * const cp; ( * 读成 pointer to ) 
cp is a const pointer to char --->cp是一个指向字符char的固定指针

const char * ptr; 
ptr is a pointer to const char; --->ptr是一个指向固定字符char的指针


char const * p; --->无此形式

 

也就是说,cp和ptr都是指针,cp的值是不可改变的cp指向的内容是可变的;而ptr的值是可以改变的,ptr指向的内容是不可变的

 

 指针的值是否可变指向的值是否可变
cpny
ptryn

 

下面写几个程序来验证之前所说的内容,并给出一个使用的小函数,期间的警告给出解决办法:

一.先来说const char *ptr

我写如下的程序:

 

预计写一个检测点分制ip是否合法的函数,我们先说明ptr,之后再改成要的形式:

现在这个函数要验证的就是对一个const char *形式的指针,指针本身的值是否可以改变,只做这一点,问题分析就要一点一点的来,不要有干扰.编译并执行:

这就说明了const char *形式的指针的地址是可以改变的,值的部分我下面验证

 

我尝试更改ptr指向的字符串的值,如下:

 

编译的时候出现的错误:

 

 

说明这个是从编译的时候就进行了安全性的检查,将错误消灭在萌芽之中,那么我们能否对值进行强行更改而骗过编译器呢?当然是可以的,我做如下的改动

 

那么虽然有一个警告,但是是可以生成可执行文件的:

 

 

无论test我生命为const char *还是 char *,都是提示一样的警告,运行的时候就产生了段错误.这就是说对编译产生的警告一定不要放过,不要以为能够生成可执行文件的程序就是正确的,事实上,只有那种unused的警告可以忽略,其他的都不要放过.

 

二.再来说char * const ptr

那么这个验证就相对简单了

 

 

编译的时候就直接出错,原因也说的很清楚,定指针不能改变自己的值,当然也不能自加;

 

 

那么我尝试修改指针指向的值:(这次使用VC调试下)

 

 

VC解释的很清除,就是说内存中的地址不能为write,也就是说ptr不仅仅是地址不能改变,连指向的值也是不能改变的.这下也基本明白了为什么那么多windows程序都会出现这个提示框了,对const理解的不深入啊,杯具~~,使用memcpy也是一致的,就不在截图了

 

三.好了,那么使用今天总结的知识来做一个使用的检测IP是否为点分值的小程序:

在socket编程中经常会用到点分制ip和unsigned long形式的ip,那么判断其有效性是提高程序健壮性的必要条件,下面只对点分制的进行判断,unsigned long形式的是系统函数生成的,inet_addr,所以无需我来担心.

 

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <unistd.h>


int check_ip(const char *buf)
{

    int i;
    int nLen;
    const char *ip = buf;
    char *tmp;
 
    nLen = strlen(ip);
    //first : check length
    if(nLen > 16 || nLen < 7)
    {
        printf("the string is too long(%s)/n", ip);
        return -1;
    }

    //second : check whether a string only has number and '.'
    for (i = 0; i < nLen; i++)
    {
        printf("11/n");
        if (ip[i] != '.' && isdigit(ip[i]) == 0) //it is not '.' or number
        {
            printf("here is not right(%c)(%d)/n", ip[i], ip[i]);
            return -1;
        }
    }

    printf("number is ok (%s)/n", ip);
 
    i = 0;
    //third, check .   

    do
    {
        tmp = strchr(ip, '.');
        printf("current(%s)/n", tmp);
  
        if(tmp != NULL)
        {
            tmp++;
            if(*tmp == '.')
            {
                printf("format error/n");
                return -1;
            }
            i++;
        }
        ip = tmp;
        //sleep(1);
    }while(tmp != NULL);

    printf("%d/n", i);
    if(i == 3)
    {
        printf("it's a string type ip/n");
        return 0;
    }
    else
    {
        printf("it's not a string type ip(%s)/n", ip);
        return -1;
    }

}


int main(int argc, char *argv[])
{
    int nRet;

    if(argc < 2)
        printf("enter a cmd like : ./test_ip 192.168.1.1");

   

    printf("(%s)/n", argv[1]);
    nRet = check_ip(argv[1]);
    printf(">>>>>>>(%d)/n", nRet);

    return 0;

 

点分制的几个安全检测如下:

1.长度是在[7,16]

2.都是有数字和'.'组成

2.不能用连续的二个'.'

3.只能有3个'.'

 

满足这4个条件的字符串就可以认为是点分制的IP地址.

这篇关于const char * 的终结贴(看完无需其他任何文章,从此不再蛋疼)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/457094

相关文章

负债不再是障碍?银行信贷“白名单“揭秘

谈及银行信贷产品,常闻有言称存在无需考量负债与查询记录之奇品,此等说法十有八九为中介诱人上钩之辞。轻信之下,恐将步入连环陷阱。除非个人资质出类拔萃,如就职于国央企或事业单位,工龄逾年,五险一金完备,还款能力卓越,或能偶遇线下产品对查询记录稍显宽容,然亦非全然无视。宣称全然不顾者,纯属无稽之谈。 银行非慈善机构,不轻易于困境中援手,更偏爱锦上添花之举。若无坚实资质,即便求助于银行亦难获青睐。反

c++的初始化列表与const成员

初始化列表与const成员 const成员 使用const修饰的类、结构、联合的成员变量,在类对象创建完成前一定要初始化。 不能在构造函数中初始化const成员,因为执行构造函数时,类对象已经创建完成,只有类对象创建完成才能调用成员函数,构造函数虽然特殊但也是成员函数。 在定义const成员时进行初始化,该语法只有在C11语法标准下才支持。 初始化列表 在构造函数小括号后面,主要用于给

java计算机毕设课设—停车管理信息系统(附源码、文章、相关截图、部署视频)

这是什么系统? 资源获取方式在最下方 java计算机毕设课设—停车管理信息系统(附源码、文章、相关截图、部署视频) 停车管理信息系统是为了提升停车场的运营效率和管理水平而设计的综合性平台。系统涵盖用户信息管理、车位管理、收费管理、违规车辆处理等多个功能模块,旨在实现对停车场资源的高效配置和实时监控。此外,系统还提供了资讯管理和统计查询功能,帮助管理者及时发布信息并进行数据分析,为停车场的科学

文章解读与仿真程序复现思路——电力自动化设备EI\CSCD\北大核心《考虑燃料电池和电解槽虚拟惯量支撑的电力系统优化调度方法》

本专栏栏目提供文章与程序复现思路,具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源程序擅长文章解读,论文与完整源程序,等方面的知识,电网论文源程序关注python

全英文地图/天地图和谷歌瓦片地图杂交/设备分布和轨迹回放/无需翻墙离线使用

一、前言说明 随着风云局势的剧烈变化,对我们搞软件开发的人员来说,影响也是越发明显,比如之前对美对欧的软件居多,现在慢慢的变成了对大鹅和中东以及非洲的居多,这两年明显问有没有俄语或者阿拉伯语的输入法的增多,这要是放在2019年以前,一年也遇不到一个人问这种需求场景的。 地图应用这块也是,之前的应用主要在国内,现在慢慢的多了一些外国的应用场景,这就遇到一个大问题,我们平时主要开发用的都是国内的地

用VB创建开始菜单快捷方式(无需其他DLL)

Option Explicit   Private Sub Command1_Click()   CreateProgManGroup Me, "测试", "test.grp"   CreateProgManItem Me, "d:\ghost.exe", "Ghost"   CreateProgManItem Me, "d:\setupQQ.exe", "QQ"   End

iOS剪贴板同步到Windows剪贴板(无需安装软件的方案)

摘要 剪贴板同步能够提高很多的效率,免去复制、发送、复制、粘贴的步骤,只需要在手机上复制,就可以直接在电脑上 ctrl+v 粘贴,这方面在 Apple 设备中是做的非常好的,Apple 设备之间的剪贴板同步功能(Universal Clipboard)确实非常方便,它可以在 iPhone、iPad 和 Mac 之间无缝传输剪贴板内容,从而大大提高工作效率。 但是,iPhone 如何和 Wind

【Linux】萌新看过来!一篇文章带你走进Linux世界

🚀个人主页:奋斗的小羊 🚀所属专栏:Linux 很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~ 目录 前言💥1、初识Linux💥1.1 什么是操作系统?💥1.2 各种操作系统对比💥1.3 现代Linux应用💥1.4 Linux常用版本 💥2、Linux 和 Windows 目录结构对比💥2.1 文件系统组织方式💥2.2

多线程的系列文章

Java多线程学习(一)Java多线程入门 Java多线程学习(二)synchronized关键字(1)   Java多线程学习(二)synchronized关键字(2) Java多线程学习(三)volatile关键字 Java多线程学习(四)等待/通知(wait/notify)机制 Java多线程学习(五)线程间通信知识点补充 Java多线程学习(六)Lock锁的使用 Java多

缓存的常见问题 以及解决博客文章

1.jedispool 连 redis 高并发卡死  (子非鱼yy) https://blog.csdn.net/ztx114/article/details/78291734 2. Redis安装及主从配置 https://blog.csdn.net/ztx114/article/details/78320193 3.Spring中使用RedisTemplate操作Redis(sprin