读嵌入式C语言精华随笔_6

这篇博客探讨了C++中数组名和指针的关系,强调了数组名在函数参数传递时如何转化为指针,并分析了其内涵和外延的变化。文章通过示例解释了`sizeof`操作符在不同情况下的行为,以及在编写`strcpy`函数时需要注意的细节,如参数类型、边界检查和返回值。此外,还讨论了如何正确判断和比较浮点数的零值,以及如何编写循环字符串右移的函数`LoopMove`。
摘要由CSDN通过智能技术生成

(1)数组名的内涵在于其指代实体是一种数据结构,这种数据结构就是数组;
(2)数组名的外延在于其可以转换为指向其指代实体的指针,而且是一个指针常量;
(3)指向数组的指针则是另外一种变量类型(在WIN32 平台下,长度为4),仅仅意味着数组的存放地址!

虽然数组名可以转换为指向其指代实体的指针,但是它只能被看作一个指针常量,不能被修改。
而指针,不管是指向结构体、数组还是基本数据类型的指针,都不包含原始数据结构的内涵,在WIN32 平台下,sizeof操作的结果都是4。

sizeof 是一个操作符!

1. #include <iostream.h>
2. void arrayTest(char str[])
3. {
4. cout << sizeof(str) << endl;
5. }
6. int main(int argc, char* argv[])
7. {
8. char str1[10] = "I Love U";
9. arrayTest(str1);
10. return 0;
11. }
程序的输出结果为4。不可能吧?
4,一个可怕的数字,前面已经提到其为指针的长度!
结论1 指出,数据名内涵为数组这种数据结构,在arrayTest 函数体内,str 是数组名,那为什么sizeof 的结果却是指针的长度?这是因为:
(1)数组名作为函数形参时,在函数体内,其失去了本身的内涵,仅仅只是一个指针;
(2)很遗憾,在失去其内涵的同时,它还失去了其常量特性,可以作自增、自减等操作,可以被修改。
所以,数据名作为函数形参时,其全面沦落为一个普通指针!它的贵族身份被剥夺,成了一个地地道道的只拥有4个字节的平民。

对基本功的掌握:
(1)字符串以’\0’结尾;
(2)对数组越界把握的敏感度;

  • (3)库函数strcpy 的工作方式,如果编写一个标准strcpy 函数的总分值为10,下面给出几个不同

得分的答案:
2 分
void strcpy( char *strDest, char *strSrc )
{
while( (*strDest++ = * strSrc++) != ‘\0’ );
}
4 分
void strcpy( char *strDest, const char *strSrc )
//将源字符串加const,表明其为输入参数,加2 分
{
while( (*strDest++ = * strSrc++) != ‘\0’ );
}
7 分
void strcpy(char *strDest, const char *strSrc)
{
//对源地址和目的地址加非0 断言,加3 分
assert( (strDest != NULL) && (strSrc != NULL) );
while( (*strDest++ = * strSrc++) != ‘\0’ );
}
10 分
//为了实现链式操作,将目的地址返回,加3 分!
char * strcpy( char *strDest, const char *strSrc )
{
assert( (strDest != NULL) && (strSrc != NULL) );
char *address = strDest;
while( (*strDest++ = * strSrc++) != ‘\0’ );
return address;
}
从2 分到10 分的几个答案我们可以清楚的看到,小小的strcpy 竟然暗藏着这么多玄机,真不是盖的!
需要多么扎实的基本功才能写一个完美的strcpy 啊!

  • 对strlen 的掌握,它没有包括字符串末尾的'\0'。

读者看了不同分值的strcpy 版本,应该也可以写出一个10 分的strlen 函数了,完美的版本为:
int strlen( const char *str ) //输入参数const
{
assert( strt != NULL ); //断言字符串地址非0
int len;
while( (*str++) != '\0' )
{
len++;
}
return len;
}

分别给出BOOL,int,float,指针变量 与“零值”比较的 if 语句(假设变量名为var)
解答:
BOOL 型变量:if(!var)
int 型变量: if(var==0)
float 型变量:
const float EPSINON = 0.00001;
if ((x >= - EPSINON) && (x <= EPSINON)
指针变量: if(var==NULL)
剖析:
考查对0 值判断的“内功”,BOOL 型变量的0 判断完全可以写成if(var==0),而int 型变量也可以写
成if(!var),指针变量的判断也可以写成if(!var),上述写法虽然程序都能正确运行,但是未能清晰
地表达程序的意思。
一般的,如果想让if 判断一个变量的“真”、“假”,应直接使用if(var)、if(!var),表明其为“逻
辑”判断;如果用if 判断一个数值型变量(short、int、long 等),应该用if(var==0),表明是与0
进行“数值”上的比较;而判断指针则适宜用if(var==NULL),这是一种很好的编程习惯。
浮点型变量并不精确,所以不可将float 变量用“==”或“!=”与数字比较,应该设法转化成“>=”
或“<=”形式。如果写成if (x == 0.0),则判为错

:编写一个函数,作用是把一个char 组成的字符串循环右移n 个。比如原来是“abcdefghi”
如果n=2,移位后应该是“hiabcdefgh”
函数头是这样的:
//pStr 是指向以'\0'结尾的字符串的指针
//steps 是要求移动的n
void LoopMove ( char * pStr, int steps )
{
//请填充...
}
解答:
正确解答1:
void LoopMove ( char *pStr, int steps )
{
int n = strlen( pStr ) - steps;
char tmp[MAX_LEN];
strcpy ( tmp, pStr + n );
strcpy ( tmp + steps, pStr);
*( tmp + strlen ( pStr ) ) = '\0';
strcpy( pStr, tmp );
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值