您的位置:首页 > 其它

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

2014-11-18 15:11 232 查看
我之前也是以为我对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指向的内容是不可变的

指针的值是否可变指向的值是否可变
cpnn
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地址.

reference:http://blog.csdn.net/scarlettsp/article/details/5949415
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: