我之前也是以为我对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指向的内容是不可变的

  指针的值是否可变 指向的值是否可变
cp n n
ptr y n

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

一.先来说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地址.

reference:http://blog.csdn.net/scarlettsp/article/details/5949415

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

  1. 【图解】你还在为 TCP 重传、滑动窗口、流量控制、拥塞控制发愁吗?看完图解就不愁了

    每日一句英语学习,每天进步一点点: 前言 前一篇「硬不硬你说了算!近 40 张图解被问千百遍的 TCP 三次握手和四次挥手面试题」得到了很多读者的认可,在此特别感谢你们的认可,大家都暖暖的. 来了,今 ...

  2. 盘点国内程序员不常用的热门iOS第三方库:看完,还敢自称”精通iOS开发”吗?【转载】

    综合github上各个项目的关注度与具体使用情况,涵盖功能,UI,数据库,自动化测试,编程工具等类型,看完,还敢自称”精通iOS开发”吗? https://github.com/syedhali/EZ ...

  3. 【转】深入理解const char*p,char const*p,char *const p,const char **p,char const**p,char *const*p,char**const p

    一.可能的组合: (1)const char*p (2)char const*p (3)char *const p(4)const char **p (5)char const**p (6)char ...

  4. c语言检测文件是否存在int __cdecl access(const char *, int);

    最近写代码,遇到很多地方需要判断文件是否存在的.网上的方法也是千奇百怪,“百家争鸣”. fopen方式打开的比较多见,也有其他各种方式判断文件是否存在的,由于其他方法与本文无关,所以不打算提及. 笔者 ...

  5. C语言中strcpy(char *strDest, const char *strScr)字符串复制库函数的理解与分析

    1.原版的strcpy()函数原型 char * strcpy( char *strDest, const char *strSrc ) { assert( (strDest != NULL) &am ...

  6. C语言中为什么不能把char**赋给const char**

    这是我在知乎回答的一个问题. 这个问题是C中的一个深坑,首先说结论: char ** 和 const char ** 是两个不相容(incompatible)的类型,能够理解为不能直接赋值 在C11的 ...

  7. QStringLiteral(源代码里有一个通过构造函数产生的从const char*到QString的隐式转换,QStringLiteral字符串可以放在代码的任何地方,编译期直接生成utf16字符串,速度很快,体积变大)

    原作者: Olivier Goffart 点击打开链接http://woboq.com/blog/qstringliteral.html 译者: zzjin 点击打开链接http://www.tuic ...

  8. c++ const char *[] or char [][]

    ]={"hello","world"}; ]={"hello"};char (*ch3)[6]= ch1; std::cout<< ...

  9. const char *p;和char * const p的区别

    const char *p;       const修饰*p,所以*p是一个常量,不可修改. char* const p; const修饰p,所以指针p是一个常量,不可修改. #include< ...

随机推荐

  1. Python入门学习教程:数据库操作,连接MySql数据库

    各位志同道合的同仁可以点击上方关注↑↑↑↑↑↑ 本教程致力于程序员快速掌握Python语言编程. 本文章内容是基于上次课程Python教程:Python教程:连接数据库,对数据进行增删改查操作 和py ...

  2. sea.js 学习

    开篇:终于学习了sea.js的使用了,因为它是一个模块加载工具,所以首先要了解javascript的模块编程,然后对sea.js的了解和使用 javascript 模块编程 为什么要模块化编程,为了让 ...

  3. 解决Win10 SVN图标不显示问题

    进入注册表HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ShellIconOverlayIdentifie ...

  4. 高性能web站点建设(一)

    一.等待 客户端发送请求到服务端相应请求的过程,是需要等待的,而等待时间的长短通常是衡量这个网站“快慢”的重要指标,在这等待的时间里,到底发生了什么?概括来说经历了以下几个部分时间: 数据在网络上传输 ...

  5. MVC 避免黄页

    可以使用HandleErrorAttribute 有两种方式可以使用它,在类或者方法的头上加 [HandleError] 这种直接在类或者方法上加[HandlerError]手动添加 另外一种方式是使 ...

  6. c语言学习之基础知识点介绍(十二):结构体的介绍

    一.结构体的介绍 /* 语法: struct 结构体名{ 成员列表; }; 切记切记有分号! 说明:成员列表就是指你要保存哪些类型的数据. 注意:上面的语法只是定义一个新的类型,而这个类型叫做结构体类 ...

  7. OpenCV(5)-图像掩码操作(卷积)-锐化

    锐化概念 图像平滑过程是去除噪声的过程.图像的主要能量在低频部分,而噪声主要集中在高频部分.图像的边缘信息主要也在高频部分,在平滑处理后,将会丢不部分边缘信息.因此需要使用锐化技术来增强边缘. 平滑处 ...

  8. (转)Libevent(3)— 基础库

    转自:http://name5566.com/4202.html 参考文献列表:http://www.wangafu.net/~nickm/libevent-book/ 此文编写的时候,使用到的 Li ...

  9. thinkphp 缓存写入失败,网站报错

    周末,正在家里休息,同事突然call 我,说网站打不开了,网站一直很正常的,突然成这样,肯定某个地方出问题了, 原来是网站所在的硬盘分区,没空间了,被mysql的日志占满了!!! 哎,好好的周末,在公 ...

  10. 《sed的流艺术之四》-linux命令五分钟系列之二十四

    本原创文章属于<Linux大棚>博客,博客地址为http://roclinux.cn.文章作者为rocrocket. 为了防止某些网站的恶性转载,特在每篇文章前加入此信息,还望读者体谅. ...