总结一下遇到的关于char *p、char p[]和字符串的题目:

例一:(指针的指针)

 1 void getmemory(char **p)
2 {
3 p = (char *)malloc(100);  //p应该是*p,因为这里是对传入的二重指针所指向的内容分配空间,而不是二重指针的地址,
4                      //所以应该为 *p = (char*)malloc(100);
5 }
6
7 int main()
8 {
9 char *str = NULL;
10 getmemory(str);        //这里应该传入&str,所以应该为 getmemory(&str);
11 strcpy(str, "hello world!");
12 printf("%s\n", str);
13 free(str);
14 while (1);
15 return 0;
16 }

例二:(局部指针传到外面)

 1 char *getstring()
2 {
3 char p[] = "hello world";
4 return p;
5 }
6
7 int main()
8 {
9 char *str = NULL;
10 str = getstring(); //用str接收getstring()函数返回的局部变量,
11 printf("%s\n", str); //但是在getstring()函数执行完时,p的内存空间就被系统回收了,也就是str所指向的空间被回收了,所以这里无法打印出hello world
12
13 while (1);
14 return 0;
15 }

例三:

 1 int main()
2 {
3 char a[4];
4 //char a;
5 char *str = &a; //这里指针级别不同,但是仍然能输出"hello",最好改为*str = a;
6 strcpy(str, "hello");
7 printf("%s\n", str);
8
9 while (1);
10 return 0;
11 }

说明:除了改变第9行的&a为a之外,按照代码中第8行和第9行的写法也可以正确输出"hello";这里a不会出现越界的问题

不妨修改一下main():

1 int main()
2 {
3 char a[4];        
4 strcpy(a, "hello");
5 printf("%s\n", a);
6
7 while (1);
8 return 0;
9 }

说明:这里a也不会出现越界的问题,最后可以输出"hello";但是如果我们把char a[4]换成char *a; 来看看会发生什么:

1 int main()
2 {
3 char *a;
4 strcpy(a, "hello");
5 printf("%s\n", a);
6
7 while (1);
8 return 0;
9 }

输出error:main.c(4): error C4700: 使用了未初始化的局部变量“a”;

说明:char *a;是在声明一个变量,是没有分配内存的,所以这里不能strcpy的;

strcpy需要复制到一个有效的,能存储字符串的空间,而a只是一个地址,能存的也是一个地址。

例四:

 1 int main()
2 {
3 char *src = "123456789";
4 int len = strlen(src);
5
6 char *dest = (char*)malloc(len);
7 char *d = dest;
8 char *s = src[len];
9
10 while (len--)
11 {
12 d++ = s--;
13
14 }
15 printf("%s\n", dest);
16
17 while (1);
18 return 0;
19 }

上面代码一堆错误,太坑了。自己不妨先看看如何改正。

错误的地方:

第8行:char *s = &src[len-1];

第12行:这里=左边的d“左操作数必须为左值”;改为d = s--; 对应15行dest改为d。

修改后源码:

 1 int main()
2 {
3 char *src = "123456789";
4 int len = strlen(src);
5
6 char *dest = (char*)malloc(len);
7 char *d = dest;
8 char *s = &src[len-1];
9
10 while (len--)
11 {
12 d = s--;
13 }
14 printf("%s\n", d);
15
16 while (1);
17 return 0;
18 }

例五:

1 int main()
2 {
3 char *s = "12345";
4 strcpy(s, "67890");
5 return 0;
6 }

说明:第3行相当于 const char *s = "12345"; 所以在第4行对s进行修改时,程序会中断。第3行改为char s[] = "12345";即可。

再看一个类似的例子:

 1 int main()
2 {
3 char s[] = "12345";
4 char *s2 = "12345";
5 const char *s3 = "12345";
6
7 strcpy(s, "67890");
8
9 printf("%s\n", s);
10
11 while (1);
12 return 0;
13 }

变量地址:

图中可以看出来:s2和s3的地址都是0x007c56e8,为常量存储区;s一个临时变量,属于栈区,所以s指向的内容可以修改,而s2,s3指向的内容则不能修改。

例六:

1 int main()
2 {
3 char *p = "linux";
4 *p = 'L';
5 printf("\n [%s] \n", p);
6
7 while (1);
8 return 0;
9 }

这个和上面的是相同的问题。第3行改为char p[] = "linux";即可。

个人总结不一定全对,欢迎指正~

char *p、char p[]、字符串的几个题目的更多相关文章

  1. 字符串复制char *strcpy(char* dest, const char *src);

    ⒈strcpy的实现代码 char * strcpy(char * strDest,const char * strSrc) { if ((NULL==strDest) || (NULL==strSr ...

  2. C 和 OC 字符串转换 NSString 和 char * 转换 const char* 与 char *

    #import <Foundation/Foundation.h> int main(int argc, const char * argv[]) { char *s = "He ...

  3. 用c++语言编写函数 int index(char *s,char * t),返回字符串t在字符串s中出现的最左边的位置,如果s中没有与t匹配的子串,则返回-1。类似于索引的功能。

    首先,分析一下程序的思路: 1:从s的第i个元素开始,与t中的第1个元素匹配,如果相等,则将s的第i+1元素与t中的第2个元素匹配,以此类推,如果t所有元素都匹配,则返回位置i;否则,执行2; 2: ...

  4. char型指针和字符串字面量和字符数组

    1.当一个char型指针指向一个字符串字面量(也就是常量字符串)时,该指针必须由const修饰,否则,系统会给出deprecated(不赞成)的警告.原因是:字符串字面量不可改变,当它被一个非cons ...

  5. 两个字符串 char* a, char* b,输出b在a中的位置次序。

    /** 题目: 两个字符串 char* a, char* b,输出b在a中的位置次序. void output_postion(const char* a, const char* b); 如:a = ...

  6. 给定一个字符串,把字符串内的字母转换成该字母的下一个字母,a换成b,z换成a,Z换成A,如aBf转换成bCg, 字符串内的其他字符不改变,给定函数,编写函数 void Stringchang(const char*input,char*output)其中input是输入字符串,output是输出字符串

    import java.util.Scanner; /*** * 1. 给定一个字符串,把字符串内的字母转换成该字母的下一个字母,a换成b,z换成a,Z换成A,如aBf转换成bCg, 字符串内的其他字 ...

  7. C++ 字符串、string、char *、char[]、const char*的转换和区别

    1.字符串 字符串本质就是一串字符,在C++中大家想到字符串往往第一反应是std::string(后面简称string) 字符串得从C语言说起,string其实是个类,C语言是没有class的,所以C ...

  8. char* 和char[]的区别

    以下内容均来自互联网,系笔者汇总并总结. 1. 问题介绍 问题引入:在实习过程中发现了一个以前一直默认的错误,同样char *c = "abc"和char c[]="ab ...

  9. char*和char []

    1.char *s1 = "ssss"; 2.char s2[] = "bbbb"; 对于第一种,我是无法理解,无法想象字符串赋值给一个char类型的指针,查了 ...

随机推荐

  1. 【UE4】GAMES101 图形学作业5:光线与物体相交(球、三角面)

    总览 在这部分的课程中,我们将专注于使用光线追踪来渲染图像.在光线追踪中最重要的操作之一就是找到光线与物体的交点.一旦找到光线与物体的交点,就可以执行着色并返回像素颜色. 在这次作业中,我们要实现两个 ...

  2. 集合先从ArrayList开始

    本篇文章非常建议直接从经典Demo开始哦~ 一.ArrayList简介 ArrayList 的底层是数组队列,相当于动态数组.与 Java 中的数组相比,它的容量能动态增长.在添加大量元素前,应用程序 ...

  3. 【Azure 应用服务】App Service For Linux 部署Java Spring Boot应用后,查看日志文件时的疑惑

    编写Java Spring Boot应用,通过配置logging.path路径把日志输出在指定的文件夹中. 第一步:通过VS Code创建一个空的Spring Boot项目 第二步:在applicat ...

  4. HttpContext.Current.Request.Url 地址:获取域名

    假设当前页完整地址是:http://www.test.com/aaa/bbb.aspx?id=5&name=kelli 协议名----http://域名  ---- www.test.com站 ...

  5. 链表中倒数第K个结点 牛客网 程序员面试金典 C++ Python

    链表中倒数第K个结点 牛客网 程序员面试金典 C++ Python 题目描述 输入一个链表,输出该链表中倒数第k个结点. C++ /* struct ListNode { int val; struc ...

  6. hdu 2200 Eddy's AC难题(简单数学。。)

    题意: N个人,每个人AC的题数都不一样. Eddy想从中选出一部分人(或者全部)分成两组.必须满足第一组中的最小AC数大于第二组中的最大AC数. 问共有多少种不同的选择方案. 思路: 简单数学.. ...

  7. linux网络编程 IO多路复用 select epoll

    本文以我的小型聊天室为例,对于服务器端的代码,做了三次改进,我将分别介绍阻塞式IO,select,epoll . 一:阻塞式IO 对于聊天室这种程序,我们最容易想到的是在服务器端accept之后,然后 ...

  8. LeetCode 重排链表 OPPO笔试

    重排链表 几个关键点: 1. 双指针(快慢指针找中点)(用于反转后一部分) 2. 反转后一部分 (reverse函数) 3. 合并链表 合并的时候在笔试的时候想了一种比我之前想的简单的方法 从slow ...

  9. 权限控制-RBAC(Role-Based Access Control)

    RBAC是基于角色的权限访问控制,在RBAC中角色与权限相连,用户通过成为某个角色而得到角色的权限,这就极大的简化了权限的管理,用户和角色多对多,角色和权限多对多,由此产生用户表.角色表.权限表,用户 ...

  10. 『学了就忘』Linux基础命令 — 38、Linux中光盘的挂载

    目录 步骤一:创建一个空目录 步骤二:找到光盘的设备文件名称 步骤三:挂载光盘 步骤四:访问关盘中的数据 步骤五:卸载挂载点 问题:挂载点为什么要使用空目录 提示:关于Linux系统中光盘的挂载,我们 ...