C语言交换2个char[100]的值

绿色 发布于 2014/10/06 17:42
阅读 1K+
收藏 1

char a[100]="this is a"';

char b[100]="this is b";

现在想交换a b

导致

for(int i=0;i<strlen(a);i++)

    printf("%c",a[i]);

输出的是"this is b";

不能用strcpy这样的,要的是交换指针

这样的是可以的

我现在就像仔细搞清楚

char *a="this is a"

跟char a[100]="this is a"

的具体区别





是可以的

就是段错误

加载中
0
wgjak47
wgjak47
char *a和char a[100]其实都是指针,指向的都是“this is a”的首字母地址,即“t”的地址。所不同的是char *a是指针变量,既可以进行++,--等操作,而char a[100]中的a为指针常量是不能进行++,--,也不能改变a所指向的地址地址。
0
绿色
绿色

引用来自“wgjak47”的评论

char *a和char a[100]其实都是指针,指向的都是“this is a”的首字母地址,即“t”的地址。所不同的是char *a是指针变量,既可以进行++,--等操作,而char a[100]中的a为指针常量是不能进行++,--,也不能改变a所指向的地址地址。

我刚也搜到了这个,如果一个指针的char a

就是char a

类似于都是const char *不能修改了

但是比如我要实现一个功能

手动输入2个字符串然后再交换2个串的值

这个时候我肯定是

char a[MAX];

char b[MAX];

然后scanf()2个串啊


char *p="2222";

虽好但是它貌似必须在申明的时候赋值



0
DavidWTF
DavidWTF
当然有区别啦……所有字符串都是在静态存储区存放的。char*a="……"是定义一个变量是char*型的,它的值被始化为"……"的地址。而char a[100]是声明一个char型的数组,并用"……"初始化这个数组。这个数组的存储空间会分配到堆栈中。大多数情况C编译器会自动把数组和指针相同对待。但两者是有区别的。数组a本身就是一个地址值,而指针a是保存了一个地址的变量,可能是寄存器中保存也可能是堆栈中保存。在不同c文件间可能无法自动转化,比如你在一个.c文件中定义一个char t[100];而在另一个.c文件中用extern char* t;然后使用t就肯定会出错。
绿色
绿色
char *a; scanf("this is a",a); 段错误 char *a; scanf("this is a",&a); 确是可以的 我现在想实现 a b 2个字符串 然后scanf扫进去 我始终用a表示那个长一点的字符串 如果a短 那么交换a b指针值
0
Micooz
Micooz

哈,这也是老生常谈的问题了。下面简单解释一下:

首先这两个字符串"this is a"其实是同一个字符串,这里的同一个,意思是静态存储区仅仅存储一份。

那么,取地址&"this is a"就是一样的了。好了,先有这个概念,再说下面的。

char *a="this is a",这个a是指针对吧,他存放的是一个地址,显然就是&"this is a",也就是这个字符串的首地址 ,就这个意思,很简单。

char a[100]="this is a",这个就不一样了哈,首先,编译期就决定了这个a数组占据100字节,至于里面放什么,在执行到这条语句后才知道。那么,如何执行,再简单解释下:

刚才说了"this is a"就放在静态存储区不会变,初始化时,程序进行内存拷贝, 依次拷贝字符串的每个字节(也可以是按双字拷贝)到a数组。

很多时候我们都把数组名当作一个const指针也不是没有道理,正如楼上所言。

区别在于此。

0
绿色
绿色

引用来自“Micooz”的评论

哈,这也是老生常谈的问题了。下面简单解释一下:

首先这两个字符串"this is a"其实是同一个字符串,这里的同一个,意思是静态存储区仅仅存储一份。

那么,取地址&"this is a"就是一样的了。好了,先有这个概念,再说下面的。

char *a="this is a",这个a是指针对吧,他存放的是一个地址,显然就是&"this is a",也就是这个字符串的首地址 ,就这个意思,很简单。

char a[100]="this is a",这个就不一样了哈,首先,编译期就决定了这个a数组占据100字节,至于里面放什么,在执行到这条语句后才知道。那么,如何执行,再简单解释下:

刚才说了"this is a"就放在静态存储区不会变,初始化时,程序进行内存拷贝, 依次拷贝字符串的每个字节(也可以是按双字拷贝)到a数组。

很多时候我们都把数组名当作一个const指针也不是没有道理,正如楼上所言。

区别在于此。

char *a; scanf("this is a",a); 段错误 char *a; scanf("this is a",&a); 确是可以的 我现在想实现 a b 2个字符串 然后scanf扫进去 我始终用a表示那个长一点的字符串 如果a短 那么交换a b指针值
0
Micooz
Micooz
char *a = "this is a";
00EB13E8  mov         dword ptr [a],0EB5858h  //

    char b[100] = "this is a";
00EB13EF  mov         eax,dword ptr ds:[00EB5858h]  // 注意这两个地址就是"this is a"的首地址了,可以发现是一样的
00EB13F4  mov         dword ptr [b],eax  
00EB13F7  mov         ecx,dword ptr ds:[0EB585Ch]  
00EB13FD  mov         dword ptr [ebp-74h],ecx  
00EB1400  mov         dx,word ptr ds:[0EB5860h]  
00EB1407  mov         word ptr [ebp-70h],dx

附反汇编代码,也方便大家理解哈。

0
绿色
绿色

引用来自“Micooz”的评论

char *a = "this is a";
00EB13E8  mov         dword ptr [a],0EB5858h  //

    char b[100] = "this is a";
00EB13EF  mov         eax,dword ptr ds:[00EB5858h]  // 注意这两个地址就是"this is a"的首地址了,可以发现是一样的
00EB13F4  mov         dword ptr [b],eax  
00EB13F7  mov         ecx,dword ptr ds:[0EB585Ch]  
00EB13FD  mov         dword ptr [ebp-74h],ecx  
00EB1400  mov         dx,word ptr ds:[0EB5860h]  
00EB1407  mov         word ptr [ebp-70h],dx

附反汇编代码,也方便大家理解哈。

超级感谢大哥
0
Micooz
Micooz

引用来自“Micooz”的评论

哈,这也是老生常谈的问题了。下面简单解释一下:

首先这两个字符串"this is a"其实是同一个字符串,这里的同一个,意思是静态存储区仅仅存储一份。

那么,取地址&"this is a"就是一样的了。好了,先有这个概念,再说下面的。

char *a="this is a",这个a是指针对吧,他存放的是一个地址,显然就是&"this is a",也就是这个字符串的首地址 ,就这个意思,很简单。

char a[100]="this is a",这个就不一样了哈,首先,编译期就决定了这个a数组占据100字节,至于里面放什么,在执行到这条语句后才知道。那么,如何执行,再简单解释下:

刚才说了"this is a"就放在静态存储区不会变,初始化时,程序进行内存拷贝, 依次拷贝字符串的每个字节(也可以是按双字拷贝)到a数组。

很多时候我们都把数组名当作一个const指针也不是没有道理,正如楼上所言。

区别在于此。

引用来自“绿色”的评论

char *a; scanf("this is a",a); 段错误 char *a; scanf("this is a",&a); 确是可以的 我现在想实现 a b 2个字符串 然后scanf扫进去 我始终用a表示那个长一点的字符串 如果a短 那么交换a b指针值

哈,这个问题,又涉及到另一个问题了。

char *a; scanf("this is a",a); 报错,有果必有因,哈。

首先这个指针a没初始化就放在那儿(栈区),没有指向,或者说不知道指在哪儿去了,如果是Debug,通常是指向0xcccccccc,如果栈被初始化过,那么a指向0x00000000。scanf函数将用户输入写到传入的地址中,问题来了,对于一个没有指向的指针,scanf将输入写到了一个不正确的地方 ,当然crash了。

 char *a; scanf("this is a",&a); 这个,又不一样了哈。

a指针放在栈里,他本身有一个地址,而且这个地址可能是一个合法地址,注意是可能哈。

scanf将输入写入到一个可能是合法的位置,有可能是不会报错的,就像你测试的结果那样。 

如果你写入一段超长的数据,不妨试试看会不会crash哈。


返回顶部
顶部