此段转自:https://blog.csdn.net/u012611878/article/details/78291036
首先 这两种类型都可以对应一个字符串,比如:
char * a=”string1”;
char b[]=”string2”;
printf(“a=%s, b=%s”, a, b);
其中a是一个指向char变量的指针,b则是一个char数组(字符数组),
其次 ,很多时候二者可以混用,像函数传参数的时候,实参可以是char*,形参可以是 char[],比如:
void fun1(char b[]){
printf("%s",b);
int main(){
char *a="HellowWorld";
fun1(a);
反过来,实参可以是char[],形参可以是 char *也是可以的。
存在即合理,char *和char[]肯定是有本质的不同。
1.char*是变量,值可以改变, char[]是常量,值不能改变。
比如:
char * a="string1";
char b[]="string2";
a=b;
a="string3";
b=a;
b="string3";
解释: a是一个char型指针变量,其值(指向)可以改变; b是一个char型数组的名字,也是该数组首元素的地址,是常量,其值不可以改变 。
2.char[]对应的内存区域总是可写,char*指向的区域有时可写,有时只读
比如:
char * a="string1";
char b[]="string2";
gets(a);
gets(b)
解释: a指向的是一个字符串常量,即指向的内存区域只读; b始终指向他所代表的数组在内存中的位置,始终可写!
注意,若改成这样gets(a)就合法了:
char * a="string1";
char b[]="string2";
a=b;
gets(a)
printf("%s",b)
解释: a的值变成了是字符数组首地址,即&b[0],该地址指向的区域是char *或者说
char[8],习惯上称该类型为字符数组,其实也可以称之为“字符串变量”,区域可读可写。
注意:char *本身是一个字符指针变量,但是它既可以指向字符串常量,又可以指向字符串变量,指向的类型决定了对应的字符串能不能改变。
3.char * 和char[]的初始化操作有着根本区别:
char *a="Hello World";
char b[]="Hello World";
printf("%s, %d\n","Hello World", "Hello World");
printf("%s, %d %d\n", a, a, &a);
printf("%s, %d %d\n", b, b, &b);

结果可见:尽管都对应了相同的字符串,但”Hellow World”的地址 和 a对应的地址相同,与b指向的地址有较大差异;&a 、&b都是在同一内存区域,且&bb
根据c内存区域划分知识,我们知道,局部变量都创建在栈区,而常量都创建在文字常量区,显然,a、b都是栈区的变量,但是a指向了常量(字符串常量),b则指向了变量(字符数组),指向了自己(&bb==&b[0])。
说明以下问题:
- char * a=”string1”;是实现了3个操作:
1声明一个char*变量(也就是声明了一个指向char的指针变量)。
2在内存中的文字常量区中开辟了一个空间存储字符串常量”string1”。 3返回这个区域的地址,作为值,赋给这个字符指针变量a
最终的结果:指针变量a指向了这一个字符串常量“string1” (注意,如果这时候我们再执行:char *
c=”string1”;则,c==a,实际上,只会执行上述步骤的1和3,因为这个常量已经在内存中创建)
- char b[]=”string2”;则是实现了2个操作:
1声明一个char 的数组, 2为该数组“赋值”,即将”string2”的每一个字符分别赋值给数组的每一个元素,存储在栈上。
最终的结果:“数组的值”(注意不是b的值)等于”string2”,而不是b指向一个字符串常量
PS:
实际上, char * a=”string1”; 的写法是不规范的!
因为a指向了即字符常量,一旦strcpy(a,”string2”)就糟糕了,试图向只读的内存区域写入,程序会崩溃的!尽管VS下的编译器不会警告,但如果你使用了语法严谨的Linux下的C编译器GCC,或者在windows下使用MinGW编译器就会得到警告。
所以,我们还是应当按照”类型相同赋值”的原则来写代码:
const char * a=”string1”;
保证意外赋值语句不会通过编译。
const char * a="string1"
char b[]="string2";
1.a是const char 类型, b是char const类型 ( 或者理解为 (const char)xx 和 char (const xx) )
2.a是一个指针变量,a的值(指向)是可以改变的,但a只能指向(字符串)常量,指向的区域的内容不可改变;
3.b是一个指针常量,b的值(指向)不能变;但b指向的目标(数组b在内存中的区域)的内容是可变的
4.作为函数的声明的参数的时候,char []是被当做char *来处理的!两种形参声明写法完全等效!
可以直接进行赋值,示例如下:
int main()
char c_str_array[] = "veryitman.com";
char *p_str;
p_str = c_str_array;
printf("p_str: %s\n", p_str);
return 0;
不能直接向上面那样转,可使用strnpy:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main()
char c_str_array[] = "veryitman.com";
char *p_str = "veryitman.com";
strncpy(c_str_array, p_str, strlen(p_str));
printf("c_str_array: %s\n", c_str_array);
return 0
PS:strncpy并没有拷贝串后的\0字符,而strcpy却拷贝了。这充分说明,strncpy是为拷贝字符而生的,而strcpy是拷贝字符串而生的。但两者都不能越界拷贝。
strnpy详解见:深入理解strncpy这个函数
别再耍流氓了: 请别再用strcpy, 而用strncpy
其是数组没有为空的,只要你申请了空间(数组一定以就在栈上有自己的空间),空间里就有数据,可以输出.然而:
你用memset把数组空间全部赋值为0了,是可以判断的.但是需要判断空间的内容,即:a[i].word[0]
a[i].word是数组word[20]的首地址,当然不会为0,或者‘\0’,换成如下就是零了:也可以是\0或者NULL
for (int i=0; i<10; i++)
memset(a[i].word,0,sizeof(a[i].word));
if(a[i].word[0]==0)//这里难到不是0 ??? 那是什么???'\0'和NULL 都不对
cout<<"空了"<<endl;
复制代码 代码如下://string --> const charstring str2ch;str2ch.c_str();//=============================//string --> char *//先转为 const char , 然后 转char *char TargetFile[strlen(TorrentFileNameDown.c_str())];...
以下是该无聊的程序:
#include <stdio.h> #include <string.h>
char* get_str() { int x[10]; char str[] = "hello world! long long long long long long long!!!"; retur...
Michael J..22好的,非循环实现(是的,它意味着一个笑话).size_t CountChars(const char *s, char c){size_t nCount=0;if (s[0]){nCount += ( s[0]==c);if (s[1]){nCount += ( s[1]==c);if (s[2]){nCount += ( s[2]==c);if (s[3]){nCoun...
我现在刚在学C语言,今天想要实现一个功能:用C语言读取一个文件的指定行,(如读取a.log文件的3--5行),现在实现了读取函数, 但在main函数调用时不知道怎么接收返回的值。代码如下:#include /*读取a.log中第3行到第5行的内容*/#define MAXLIN 100#define FILENAME "a.log"char* getFileRows(char* filename,...
getchar()和putchar(变量) 及getchar()与scanf并用问题(清理缓冲区方法)
通过time()、srand()、rand()函数来进行伪随机 assert函数 调试快捷键
1、为什么作为局部变量的字符数组不能直接返回,而字符指针却可以?
2、当字符数组是局部变量的时候,函数如何返回它?
3、字符数组(char [])和字符指针(char...
在C语言中,自动变量在堆栈中分配内存。当包含自动变量的函数或代码块退出时,它们所占用的内存便被回收,它们的内容肯定会被下一个所调用的函数覆盖。这一切取决于堆栈中先前的自动变量位于何处,活动函数声明了什么变量,写入了什么内容等。原先自动变量地址的内容可能被立即覆盖,也可能稍后才被覆盖。
解决方案:
1. 返回一个指向字符串常量的指针。例如:
char* func() {
#include #include char *string_uppercase(char *string){char *starting_address;starting_address = string;while (*string)toupper(*string++);return(starting_address);}int main(void){char *title = "Jamsa'...
str为地址,返回值为char*,是进行了值传递,没有问题,但是,数组中的元素为局部变量,存在栈中,函数外无效。
1、解决方法1:将数组定义为static
char* func(char *name)
static char str[]= name;
retur...
int i;
char **s;
s =malloc(sizeof(char *)*10); //这里需要*10,因为下面使用了10个指针数组。否则会出现乱码。等价于char *s[10]
for (i=0;i<10;i++)
s[*retsize] =...