用指针交换同一字符串的两个字符
Swapping two characters of the same string with pointers
我正在尝试解决朋友发给我的一段代码。他正在练习指针并尝试使用它们来反转字符串。
这应该是一个非常简单的任务,但我的知识在这里存在差距。我已经能够成功地创建一个 for 循环,它使用 i
和 j
作为控制变量正确地遍历字符串。我也已经能够打印出需要交换的字符。
唯一的问题是 for 循环中的注释代码行。它应该交换这两个值,但抛出错误,我不明白为什么。
#include <stdio.h>
int length(char *p);
void reverse(char *);
int main() {
char *p = "Computer";
reverse(p);
}
int length(char *p) {
int i;
for (i = 0; *(p + i) != '[=10=]'; i++);
return i;
}
void reverse(char *p) {
int l, i;
char t;
for (l = 0; *(p + l) != '[=10=]'; l++);
int len = l;
int temp;
for (i = 0; i < l; i++, l--) {
t = *(p + i);
printf("i-th element - %c\n", t);
printf("j-th element - %c\n", *(p + len - 1 - i));
*(p + i) = *(p + len - 1 - i); // crash
}
puts(p);
}
我什至不确定是否可以这样交换它们。我会选择 t = p[i]; p[i] = p[i + 1]...
方法。如果有人能纠正和解释这个和指针相关的戏剧,那就太好了。
首先,您不能尝试修改字符串文字。
您应该使用(可修改的)数组:
char p[] = "Computer";
而不是
char *p = "Computer";
其次,您需要
*(p + len - 1 - i) = t;
之后
*(p + i) = *(p + len - 1 - i);
完成交换。
对于初学者,您不能更改字符串文字
char *p = "Computer";
任何更改字符串文字的尝试都会导致未定义的行为。
所以不是指向字符串文字的指针,而是声明一个字符数组,如
char s[] = "Computer";
此外,您的函数 reverse
不使用函数 length
,实际上不反转字符串。
这个循环
for (i = 0; i < l; i++, l--) {
使用两个辅助变量作为索引。
函数reverse
不输出任何内容。它要做的是反转传递的字符串。函数的调用者决定是否输出反转字符串或将其用于其他目的。
函数 length
和 reverse
可以通过以下方式仅使用指针来声明和定义
size_t length( const char *s )
{
const char *p = s;
while ( *p ) ++p;
return p - s;
}
和
char * reverse( char *s )
{
if ( *s )
{
for ( char *p = s, *q = s + length( s ); p < --q; ++p )
{
char c = *p;
*p = *q;
*q = c;
}
}
return s;
}
函数reverse可以这样调用
int main( void )
{
char s[] = "Computer";
puts( s );
puts( reverse( s ) );
}
这是一个演示程序。
#include <stdio.h>
size_t length( const char *s )
{
const char *p = s;
while ( *p ) ++p;
return p - s;
}
char * reverse( char *s )
{
if ( *s )
{
for ( char *p = s, *q = s + length( s ); p < --q; ++p )
{
char c = *p;
*p = *q;
*q = c;
}
}
return s;
}
int main( void )
{
char s[] = "Computer";
puts( s );
puts( reverse( s ) );
}
它的输出是
Computer
retupmoC
正如您在两个函数中看到的那样,用作索引的变量都不存在。这些函数仅使用指针。
使用尖点需要小心,否则到处都会出现“分段错误”。但是,让我们这样做。我使用的一种反转字符串的技术是,第一个指针指向字符串的开头,另一个指针指向字符串的结尾;并在它们到达字符串中间时促进交换(这样我将处理减少了一半)检查此代码
/* reverses a string
* !!! this function modifies input string !!!
*/
char *reverse(char *s)
{
char *h, *t, c; /* h)ead, t)ail and a temporary c */
int len = 0;
/* positioning the pointers at beginning and end of string s */
len = length(s);
h = (char*)&s[0];
t = (char*)&s[len - 1];
for (int i = 0; i < (len / 2); i++)
{
/* swap chars */
c = *h;
*h = *t;
*t = c;
/* increase h pointer, decrease t pointer */
h++;
t--;
}
return s;
}
纯指针...以任何形式交换 *h 和 *t 时你都无法摆脱临时存储 ( c );
请注意输入字符串需要声明为 char name[] 否则 sigsegv 会跟随您!
如果你想保存字符串供以后直接打印到stdout
,你可以这样做:
char * reverse(char * I){
int i,l;
char * O;
l=strlen(I);
O=malloc(l+1);
for(i=1;i<=l;i++)O[i-1]=I[l-i];
O[l]='[=10=]';
return O;
}
int main(){
char * p=reverse("Computer");
printf("%s",p);
free(p);
}
我正在尝试解决朋友发给我的一段代码。他正在练习指针并尝试使用它们来反转字符串。
这应该是一个非常简单的任务,但我的知识在这里存在差距。我已经能够成功地创建一个 for 循环,它使用 i
和 j
作为控制变量正确地遍历字符串。我也已经能够打印出需要交换的字符。
唯一的问题是 for 循环中的注释代码行。它应该交换这两个值,但抛出错误,我不明白为什么。
#include <stdio.h>
int length(char *p);
void reverse(char *);
int main() {
char *p = "Computer";
reverse(p);
}
int length(char *p) {
int i;
for (i = 0; *(p + i) != '[=10=]'; i++);
return i;
}
void reverse(char *p) {
int l, i;
char t;
for (l = 0; *(p + l) != '[=10=]'; l++);
int len = l;
int temp;
for (i = 0; i < l; i++, l--) {
t = *(p + i);
printf("i-th element - %c\n", t);
printf("j-th element - %c\n", *(p + len - 1 - i));
*(p + i) = *(p + len - 1 - i); // crash
}
puts(p);
}
我什至不确定是否可以这样交换它们。我会选择 t = p[i]; p[i] = p[i + 1]...
方法。如果有人能纠正和解释这个和指针相关的戏剧,那就太好了。
首先,您不能尝试修改字符串文字。
您应该使用(可修改的)数组:
char p[] = "Computer";
而不是
char *p = "Computer";
其次,您需要
*(p + len - 1 - i) = t;
之后
*(p + i) = *(p + len - 1 - i);
完成交换。
对于初学者,您不能更改字符串文字
char *p = "Computer";
任何更改字符串文字的尝试都会导致未定义的行为。
所以不是指向字符串文字的指针,而是声明一个字符数组,如
char s[] = "Computer";
此外,您的函数 reverse
不使用函数 length
,实际上不反转字符串。
这个循环
for (i = 0; i < l; i++, l--) {
使用两个辅助变量作为索引。
函数reverse
不输出任何内容。它要做的是反转传递的字符串。函数的调用者决定是否输出反转字符串或将其用于其他目的。
函数 length
和 reverse
可以通过以下方式仅使用指针来声明和定义
size_t length( const char *s )
{
const char *p = s;
while ( *p ) ++p;
return p - s;
}
和
char * reverse( char *s )
{
if ( *s )
{
for ( char *p = s, *q = s + length( s ); p < --q; ++p )
{
char c = *p;
*p = *q;
*q = c;
}
}
return s;
}
函数reverse可以这样调用
int main( void )
{
char s[] = "Computer";
puts( s );
puts( reverse( s ) );
}
这是一个演示程序。
#include <stdio.h>
size_t length( const char *s )
{
const char *p = s;
while ( *p ) ++p;
return p - s;
}
char * reverse( char *s )
{
if ( *s )
{
for ( char *p = s, *q = s + length( s ); p < --q; ++p )
{
char c = *p;
*p = *q;
*q = c;
}
}
return s;
}
int main( void )
{
char s[] = "Computer";
puts( s );
puts( reverse( s ) );
}
它的输出是
Computer
retupmoC
正如您在两个函数中看到的那样,用作索引的变量都不存在。这些函数仅使用指针。
使用尖点需要小心,否则到处都会出现“分段错误”。但是,让我们这样做。我使用的一种反转字符串的技术是,第一个指针指向字符串的开头,另一个指针指向字符串的结尾;并在它们到达字符串中间时促进交换(这样我将处理减少了一半)检查此代码
/* reverses a string
* !!! this function modifies input string !!!
*/
char *reverse(char *s)
{
char *h, *t, c; /* h)ead, t)ail and a temporary c */
int len = 0;
/* positioning the pointers at beginning and end of string s */
len = length(s);
h = (char*)&s[0];
t = (char*)&s[len - 1];
for (int i = 0; i < (len / 2); i++)
{
/* swap chars */
c = *h;
*h = *t;
*t = c;
/* increase h pointer, decrease t pointer */
h++;
t--;
}
return s;
}
纯指针...以任何形式交换 *h 和 *t 时你都无法摆脱临时存储 ( c );
请注意输入字符串需要声明为 char name[] 否则 sigsegv 会跟随您!
如果你想保存字符串供以后直接打印到stdout
,你可以这样做:
char * reverse(char * I){
int i,l;
char * O;
l=strlen(I);
O=malloc(l+1);
for(i=1;i<=l;i++)O[i-1]=I[l-i];
O[l]='[=10=]';
return O;
}
int main(){
char * p=reverse("Computer");
printf("%s",p);
free(p);
}