设为首页 加入收藏

TOP

字符串双引号的含义探究+字符数组+strcpy+C面试一道题(一)
2017-10-13 10:05:54 】 浏览:1686
Tags:字符串 引号 含义 探究 字符 strcpy 面试 一道

/*编写一个函数,作用是把一个char组成的字符串循环右移steps个。比如原来是“abcdefghi”如果steps=2,移位后应该是“hiabcdefgh”

#include<stdio.h>
#include<string.h>

#define MAX_LEN 100

void LoopMove ( char* pStr, int steps)
{
int n = strlen(pStr) - steps;
char tmp[MAX_LEN];
strcpy(tmp, pStr + n);
printf("%s\n", tmp);

strcpy(tmp + steps, pStr);
printf("%s\n", tmp); // hiabcdefghi

*(tmp + strlen(pStr)) = '\0';
strcpy(pStr, tmp); //定位出这句代码有问题。 ?
printf("%s\n", pStr); // 断点设在该行,gdb打印tmp,tmp是错的
}

int main(void)
{
char *name = "abcdefghi";
LoopMove(name, 2);
printf("%s\n", name);
}
*/

/*错误原因:我在试图修改一个常量
对strcpy的第一个参数,我们只能猜测:
1,传字符数数组,因为字符数组本质是变量,只是利用strcpy,借用了字符串的方式赋值,而已
2,char *name = “ ”; (含空格)
我们着重分析第二种,如果第二种成立,那我继续按照这个理解:
第二种叫做为0初始化?不管说法叫什么,反正最重要就是我们不要让name指向字符串常量就好了。
但不可能每次都用手打几个空格来用,malloc会为解决这个问题。

另外,使用双引号的空字符char *name = “”;(不含空格)和字符串常量是有区别的。确切地说空字符更像是NULL。 反思我们在链表操作时,使用到了malloc,我们是让指针平常闲
着的时候指向NULL的,然后在需要的时候让指针和malloc返回的地址等价。所以这点就验证了指向NULL的真实含义并不
是指向一个字符串常量。 NULL 在C语言中定义为 (void *)0, 指向0地址, 而char *name = “”;则可以理解为指向某个
系统分配的地址,地址上无数据,唤作 指向空地址 好了。 区别就是 一个指向0地址,一个指向空地址。可以说是
异曲同工之妙。
以上都是瞎猜扯淡---具体实验说话

待实验目录:
0 来个基本的,修改字符串常量以和下面的对比

1char *name = “ ” 是否等同字符串常量, char *name = “”呢?

2char *name = “ ” , char *name = “” , 链表操作时,使用到了malloc。 以此对比NULL

3char *p = 0; 是否报错, %d可以打印字符, 说明对内存解析时候允许程序员更灵活?,存储时要求严格

实验:
0
char *name;
int a[800] = {0}; //加这个是为了验证字符串指针初始化可以先声明,再赋值。关于字符串初始化,详见下图
name = "abcdhdrrgifghfiu";
strcpy(name, "aaaaaaaa");
printf("%s\n", name);
结果:第二个打印出现段错误,符合预期

1-1
char *name;
int a[800] = {0};
name = " ";
printf("%s\n", name);
strcpy(name, "aaaaaaaa");
printf("%s\n", name);
结果:第一个打印没问题,第二个出现段错误,不符合预期。
说明char *name = “ ”; 中name指向了字符串常量

1-2
char *name;
int a[800] = {0};
name = "";
printf("%s\n", name);
strcpy(name, "aaaaaaaa");
printf("%s\n", name);
结果同1-1.
说明char *name = “”; 中name指向了字符串常量

2
struct node *p = "";
p = (struct node *)malloc(sizeof(struct node));

struct node *p = " ";
p = (struct node *)malloc(sizeof(struct node));
编译提示差不多,都是同样的警告
aston@ubuntu:/mnt/hgfs/shared$ gcc c.c
c.c: In function ‘create_node’:
c.c:17:19: warning: initialization from incompatible pointer type [enabled by default]
struct node *p = " ";

重要问题: 从错误提示来看, 谁能回答我 “”在C语言中是什么地址类型?
本实验中,p指向的内容我们没去改,我们把p指向另一段内存,是可行的。
由此:

字符串指针,指向的字符串常量是不能改的,只能初始化一次。只要是用“”双引号来修饰了,都可以认为是字符串常量。

对“”在C语言中是什么类型的问题就不那么重要了,只要知道 你只会用它来修饰字符串 就够了。


思考步骤: 以后碰到问题先想解决问题的大步骤,别先想得那么细,应该根据实验的大步骤的结论来确定下一步的思路
这样一来能避免思路混乱,还能提高效率。
*/

//再继续解决一下上面的问题: 1,主函数传进去的是字符数数组即可,不介绍. 我这里修改子函数

#include<stdio.h>
#include<string.h>

#define MAX_LEN 100

char* LoopMove (const char* pStr, int steps)
{
char out[100]; // char *out;不可以,详见下图
int n = strlen(pStr) - steps;
char tmp[MAX_LEN];
strcpy(tmp, pStr + n);
printf("%s\n", tmp);

strcpy(tmp + steps, pStr);
printf("%s\n", tmp); // hiabcdefghi

*(tmp + strlen(pStr)) = '\0';
strcpy(out, tmp);

return out; //把局部变量返回出去会报警告,但没事
}

int main(void)
{
const char *name = "abcdefghi";
char *out;
out = LoopMove(name, 2);
printf("%s\n", out);
}

aston@ubuntu:/mnt/hgfs/shared$ ./a.out
hi
hiabcdefghi
hiabcdefg

 

           //图片在这里


/*  一直都忽视gdb,今天在这里用上了
1.编译生成可执行文件 gcc -g test.

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇每天一个Linux命令 7 下一篇字符串双引号的含义探究+字符数组..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目