C 风格字符串和strcpy方法的实现

C语言是面向过程的,所以它并没有所谓封装好的功能强大的string。但是麻雀虽小五脏俱全。在C中,我们一般用

const char* 类型来定义一个字面型字符串。

首先我们了解下C中的基本指针。指针是存储变量地址的变量。而我们主要来区别下数组指针和普通指针。

看一段代码:

char c = ‘d‘;
char* ptr_c  = &c;

printf(ptr_c);

这段代码是能通过编译的,然而执行的时候会出现不可预期的错误。虽然printf接受的是一个const char* 类型的参数。但是显然不是所有的char* 类型的参数都是它所预期能接受的。

上述的ptr_c是一个指向单个字符char的地址。如果对其进行+ - 运算,那么获得的地址将是不可预期的。

我们修改一下:

char cstring[3];

ptr_c = cstring;  //1
*(ptr_c++) = ‘a‘; //2
*(ptr_c++) = ‘b‘;
*(ptr_c) = ‘\0‘;    //3

printf("%c ",*cstring); //4
printf(cstring);            //5

上述代码虽然简单,但是句句暗藏玄机。

1.cstring是数组的名字,但是创建数组的时候,他会自动创建一个指针。这个指针可以赋值给一个char类型的指针。是一个右值(所以也可以看成是头指针)。

这行代码等价于:

ptr_c = &cstring[0];

此外,这个数组的所有元素的地址是按照一定的规则排列的,所以指针的+ -运算可以得到对应元素的地址。比如,第一个元素的地址+2就是第三个元素的地址,但计算的时候一定要注意不要越过数组的界限。

2.*(ptr_c++) 的操作步骤是先解引用,然后将指针+1。对于理解上很容易误解,很容易看成是先将指针+1再解引用。这是不对的。要注意。

3.一定注意:c语言的字符串约束是末尾字符是\0,也就是说满足末尾字符是\0的的字符数组就可以当作c字符串来使用。

4.同1,cstring解引用后会获得第1个元素的值。

5.c语言中所有const char* 类型的参数或者返回值,都可以当作是字符串。他们满足的约束也是尾字符是\0。所以这次我们传一个真正的字符串进去,printf(const char *)方法才能正确执行。

了解了这么多,相比大家早就对实现strcpy方法跃跃欲试。这是c最经典的一道面试题,同时也囊括了刚才介绍的不少知识点。

char* strcpy(char* dest, const char* src)

{

  assert(dest != NULL && src != NULL);

  char* ret = dest;

  while(*(dest++) = *(src++) != ‘\0‘);

       return ret;  

}

最后说下,C中的字符串字面值常量,编译器将视他为const char*类型。所以可以直接赋值。
此外,const char* 被赋值后,这个值就不能再变化,我曾经试着作死但是明显失败了
const char* ntr = "ninij";
char* str = const_cast<char*> (ntr);
*str = ‘a‘;
printf(ntr);//严重报错,一旦str被赋值,原ntr的结构被破坏!!慎重!!!

对此我们需要理解下const的作用:
常量指针,表述为“是常量的指针”,它首先应该是一个指针。
指针常量,表述为“是指针的常量”,它首先应该是一个常量。

常量指针 const char *p; p指向的内容不可变
指针常量 char* const p; p指向的地址不可变

时间: 2024-10-15 03:28:17

C 风格字符串和strcpy方法的实现的相关文章

c语言:两种方法实现字符串拷贝strcpy

实现字符串拷贝strcpy 方法一: // 字符串拷贝函数的实现 #include<stdio.h> #include<assert.h> void my_strcpy(char *dest,  char *src)//src表示source源,dest目标 { assert(dest!=NULL); assert(src); char *ret = dest; while (*dest++ = *src++) { ; } return dest; } int main() { c

string字符串转C风格字符串 进而转换为数字

要求如题 头文件stdlib.h中有一个函数atof() 可以将字符串转化为双精度浮点数(double) double atof(const char *nptr); 此字符串为C风格字符串,因此需要将string转化为C风格字符串 此时可用到一个函数c_str() const char *c_str() 参考资料: string中c_str().data().copy(p,n)函数的用法 在使用c_str()时遇到了一个问题–此函数的返回值为const char * 因为是const数据类型,

C风格字符串

尽管C++支持C风格字符串,但在C++程序中最好还是不要使用它们.这是因为C风格字符串不仅使用起来不太方便,而且极易引发程序漏洞,是诸多安全问题的根本原因. 字符串字面值是一种通用结构的实例,这种结构即是C++由C继承而来的C风格字符串.C风格字符串不是一种类型,而是为了表达和使用字符串而形成的一种约定俗成的写法.按此习惯书写的字符串存放在字符数组中并以空字符串结束.以空字符结束的意思是在字符串最后一个字符后面跟着一个空字符('\0').一般利用指针来操作这些字符串. C标准库String函数

【C++ Primer每日一刷之八】之八 C 风格字符串

4.3 C 风格字符串 尽管 C++ 支持 C 风格字符串,但不应该在 C++ 程序中使用这个类型.C 风格字符串常常带来许多错误,是导致大量安全问题的根源. 在前面我们第一次使用了字符串字面值,并了解字符串字面值的类型是字符常量的数组,现在可以更明确地认识到:字符串字面值的类型就是const char 类型的数组.C++ 从 C 语言继承下来的一种通用结构是C 风格字符串,而字符串字面值就是该类型的实例.实际上,C 风格字符串既不能确切地归结为 C 语言的类型,也不能归结为 C++ 语言的类型

C风格字符串与C++风格字符串

C风格字符串与C++风格字符串 C风格字符串:对字符串进行操作的 C 函数定义在头文件<cstring>中: 1. 字符串定义:char* result: 2. 字符串的最后一个字符是null字符('\0'),可以通过这个字符确定字符串的结尾. 3. strlen()返回的是字符串的大小:因此,分配空间的时候,需要比字符串的实际空间大1. e.g. char* copyString(const char* inString) { char *result = new char[strlen(i

大话设计模式实战之工厂方法的实现——链接数据库应用

工厂方法的优点在这里不说了,网上搜索一大堆,自己看 如果使用JDBC链接数据库,数据库从MySql切换到Oracle,需要改动的就是切换一下驱动的名称,其他的都不需要修改,这就是工厂方法灵活性的一个直接的例子 纸上谈兵空谈 上代码: public abstract class AbstractSqlFactory { //这个就是泛型的类的实例就是需要控制的在JDK1.5中的特性 public abstract <T extends SqlUtil> T createSql(Class<

C++ 标准头文件与C头文件区别与联系以及C风格字符串

1.cstdlib是C++里面的一个常用头文件, 等价于C中的<stdlib.h>. 2.一般一个带".h" 扩展名的库文件,比如iostream.h.这是延续C语言的,为了兼容C.在新标准的库中都有一个 不带".h"扩展名的相对应,区别除了后者好多改进之处,还有一点就是后者的东西都放进了"std"名字空间中. 但是 string.h有点特别,问题在于C++要兼容C的标准库,C的标准库里也有一个名字叫做"string.h&q

关于Java中hashCode方法的实现源码

首先来看一下String中hashCode方法的实现源码. public int hashCode() { int h = hash; if (h == 0 && value.length > 0) { char val[] = value; for (int i = 0; i < value.length; i++) { h = 31 * h + val[i]; } hash = h; } return h; } 在String中有一个私有实例字段hash表示该串的哈希值,在

【共读Primer】19.&lt;3.5&gt; 数组-C风格字符串 Page109

C风格的字符串是指以空字符'\0'结尾的一个字符串. 这种字符串虽然在C++中兼容,但是极易引起内存安全问题,所以不建议使用. 但是作为一个语言特性,我们应该了解它,这样才能在碰到的时候做到心中有数. 3.5.4 C标准库string函数 这里所说的string函数并不是std::string的函数,而是在C的标准库中,对C风格字符串进行操作的一些全局函数. strlen(p); //计算p的长度,不计入空字符结尾 strcmp(p1, p2); // 比较两个字符串p1和p2是否相等,相等返回