[C++][基础概念](三)char的学习

一、定义char:char p[n];表示定义了含有n个元素的char型,注意其中最大地址是p[n-1],char p[3]="abc";编译器会报错,因为还要含有'\0'。

二、char a[];和char* a的区别:

char a[];a代表的是字符串的首地址,s保存的也是字符串的首地址,这样看来a和s就完全一样,但事实不是这样。

(1)char* s1="abc";s1是一个指针,这个指针可以被修改,它可以指向新的指针,但是字符串常量存储在constant section中,不可被修改,当我们s1="def"时,修改的不是"abc"中的内容,而是将s1指向了新的地址空间。
(2)char a[5]="abc";a是数组指针,指针指向的位置是数组的第一个元素所在的位置,一旦分配,便无法修改,它的空间分配在栈中,但我们可以修改它的内容。
比如下面的例子很好地说明了这点:

#include<stdio.h>
int main() {
	char* s1 = "abc";
	printf("%p\n", s1);//00CA6BD4
	s1 = "def";
	printf("%p\n", s1);//00CA6B34
	char a[5] = "abc";
	printf("%p\n", a);//0018FBD0
	a[0] = "d";
	printf("%p\n", a);//0018FBD0
	while (1);
	return 0;
}

从上我们可以看出 修改s1时,其位置发生了变化,而修改a时,其位置并未变化
#include<stdio.h>
#include<iostream>
using namespace std;
int main() {
	char *p="abc";
	//*p ="d";
	printf("%s\n", p);//abc
	cout << p << endl;//abc
	cout << *p << endl;//a
	while (1);
	return 0;
}
有几个问题:
1.
char *p="abc";
*p ='d';
编译没有出错,但运行时报错,p是个指针,*p是p所指的位置即是a,但因为如上所述"abc"是字符串常量,存储在constant section中,不可修改。这个问题也说明了redis的sds.c中的sddsll2str中的程序为什么无法运行的原因。
2.
char *p="abc";
p ='d';
报错,无法从char转换为char *

修改成 p="de"就可以成功了。

三、在string.h中的一些函数的学习

      1.strchr() 用来查找某字符在字符串中首次出现的位置,其原型为:

char * strchr (const char *str, int c);

[参数] str 为要查找的字符串,c 为要查找的字符。
strchr() 将会找出 str 字符串中第一次出现的字符 c 的地址,然后将该地址返回。
注意:字符串 str 的结束标志 NUL 也会被纳入检索范围,所以 str 的组后一个字符也可以被定位。
[返回值]如果找到指定的字符则返回该字符所在地址,否则返回 NULL。
返回的地址是字符串在内存中随机分配的地址再加上你所搜索的字符在字符串位置。设字符在字符串中首次出现的位置为 i,那么返回的地址可以理解为 str + i。

      2.memmove和memcpy的区分

      memcpy和memmove()都是C语言中的库函数,在头文件string.h中,作用是拷贝一定长度的内存的内容,原型分别如下:

void *memcpy(void *dst, const void *src, size_t count);

void *memmove(void *dst, const void *src, size_t count);

他们的作用是一样的,唯一的区别是,当内存发生局部重叠的时候,memmove保证拷贝的结果是正确的,memcpy不保证拷贝的结果的正确。(只是不保证是正确的,不是说一定是不正确的)。

代码举例和分析:

#include <stdio.h>
#include <string.h>
#include<assert.h>
void* mymemcpy(void* dst, void* src, size_t size)
{
    assert(dst != NULL && src != NULL);
    char* temsrc = (char*)src;
    char* temdst = (char*)dst;
    while(size--)
        *temdst++ = *temsrc++;
    return dst;
}


void* mymemmove(void* dst,const void* src,size_t count)
{
assert(NULL !=src && NULL !=dst);
char* tmpdst = (char*)dst;
char* tmpsrc = (char*)src;
//如果dst在src前面,或者dst在src后面,但是他两的距离超过 count,可以直接从前往后复制,不会出现覆盖的结果
if (tmpdst <= tmpsrc || tmpdst >= tmpsrc + count)
{
    while(count--)
    {
        *tmpdst++ = *tmpsrc++;
    }
}
else//否则,从后往前复制
{
    tmpdst = tmpdst + count - 1;
    tmpsrc = tmpsrc + count - 1;
    while(count--)
    {
        *tmpdst-- = *tmpsrc--;
    }
}

return dst;
}

int main(){
    char s[]="1234567890";
    char* p1=s;
    char* p2=s+2;
    //mymemcpy(p2,p1,5);//12121890
    //printf(p2);
    mymemmove(p2,p1,5);//12345890
    printf(p2);

    return 0;
}
      3.

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值