C语言里定义一个字符串可以使用指针也可以使用数组,如:
(1) char *s="hello"; //"hello"是字符串常量,s是指向常量的指针,常量是不允许改变的,不能写成s[0]=X,但可以改变指针的值,使其指向不同的常量,如 s = "Xeron";
(2) char s[]="hello"; //指针常量,s本身的值不能修改,但可以修改其指向的内容,s[0]=X
两者的区别是
(1)定义的字符串在程序里不能被修改,因为它存放在代码段内;
(2)定义的字符串可被修改,它存放在数据段或者栈内。
这两种定义字符串的方法在函数内部和外部稍有区别
*函数外部:
(1) char *s="hello"; /*定义了指针s(数据段)和常量字符串"hello"(数据段),s的值为字符串首地址*/
(2) char s[]="hello"; /*定义了字符数组s,数组内容为"hello"(代码段),注意这里s只是一个符号而不是变量实体*/
*函数内部:
如果在函数内部使用(1),(2)定义,则"hello"字符串本身存放在代码段,当函数被调用时,
(1) 仅把字符串"hello"的首地址地址赋给s
(2) 把字符串"hello"拷贝一份放到栈内,把拷贝串的首地址赋给s
所以(1)中s所指的内容不能改变,而(2)中s所指的串可修改,s指向的是"hello"串的拷贝,不会影响原串,每次调用函数的时候都拷贝一次
注:在函数内部使用(1)(2)是没有加static关键字修饰的,如果加了static关键字,那就跟在函数外部没什么区别了.
******************************
(1)稍加改变就能满足"hello"串可修改
char *s = (char []){"hello"}; //好像不可行
此时匿名"hello"串存放在数据段。
也可以给定义一个匿名数组赋给int型指针,如:
int *p=(int [10]){[0 ... 9]=0};
----------------------------------------------------------------------------------------
malloc()和free()的基本概念以及基本用法:
1、函数原型及说明:
void *malloc(long NumBytes):该函数分配了NumBytes个字节,并返回了指向这块内存的指针。如果分配失败,则返回一
个空指针(NULL)。
关于分配失败的原因,应该有多种,比如说空间不足就是一种。
void free(void *FirstByte): 该函数是将之前用malloc分配的空间还给程序或者是操作系统,也就是释放了这块内存,
让它重新得到自由。
2、函数的用法:
其实这两个函数用起来倒不是很难,也就是malloc()之后觉得用够了就甩了它把它给free()了,举个简单例子:
程序代码:
// Code...
char *Ptr = NULL;
Ptr = (char *)malloc(100 * sizeof(char));
if (NULL == Ptr)
{
exit (1);
}
gets(Ptr);
// code...
free(Ptr);
Ptr = NULL;
// code.
代码如下:
#include<stdio.h>
void str_copy(char *from,char *to);
main()
{ char *a="I am chinese!";
char aa[20]="sssssssssssssssssss";
char * b;
b=aa;
str_copy(a,b);
printf("字符串拷贝后:\n");
printf("%s",aa); //或者 printf("%s",b); 都成功!!
printf("\n");
}
void str_copy(char *from,char *to)
{
while(*to++ = *from++);
}
但是我改为一下代码,却出现了段错误:
#include<stdio.h>
void str_copy(char *from,char *to);
main()
{ char *a="I am chinese!"; //对指针变量直接赋值是可以的。这时初始化指针时所创建的字符串常量被定义为只读。即*a内容不能变
char *b="ssssssssssssssssssssss"; //对指针变量直接赋值是可以的。这时初始化指针时所创建的字符串常量被定义为只读。即*b内容不能变
str_copy(a,b);
printf("字符串拷贝后:\n");
printf("%s",b);
printf("\n");
}
void str_copy(char *from,char *to)
{
while(*to++ = *from++);
}
所谓段错误就是一般指指针未赋值,就是所谓的野指针,但是这种char *b="ssssssssssssssssssssss";字符串定义不是给b分配了指向数组的地址了吗?为什么会出现这种情况呢?
#include "stdafx.h"
char *strcpy_v1(char *dest , const char *src)
{
//调试时,使用断言,入口检测
assert( (dest!=NULL) && (src!=NULL) );
//注意这里的内存指向参数dest所在的内存,不是栈内存,因而可以在函数中返回
char *to = dest;
//主要操作在while条件中完成
while( (*dest++ = *src++)!='\0') //判断是否赋值是'\0'
{
NULL;
}
//返回拷贝字符串首地址,方便连缀,比如strlen(strcpy(dest,"hello"))
return to;
}
/*
* 说明:字符串拷贝版本2
* 参数:dest目标地址,src源地址
* 返回:返回拷贝好的地址;如果出错,无定义
* 异常:可能出现字符串溢出,及dest所占空间不如src所占空间大。
*/
char *strcpy_v2(char *dest , const char *src)
{
char *d = dest;
char c;
while((c=*src++) != '\0')
{
*(dest++)=c;
}
*dest='\0';
return d;
}
/*
* 说明:字符串拷贝版本2(你能找出错误的原因吗)
* 参数:dest目标地址,src源地址
* 返回:返回拷贝好的地址;如果出错,无定义
* 异常:可能出现字符串溢出,及dest所占空间不如src所占空间大。
*/