总有人说c语言的三座大山及,指针,函数,数组,在学习当中给我们带来了很大的困扰,对抽象问题无法理解,好,很高兴我翻越了其中一座山,接下来我会分享这三个问题的学习方法,每个章节后面都会附有练习题,需要着重强调的是,题一定要自己想办法敲一下,对概念的理解和发现问题有很大的帮助,好了,祝大家尽快渡过难关!!!
- 指针的定义:
格式: <存储类型> <数据类型> * 变量名称;
eg: char * pc;
==》数据类型用于标识目标存储空间大小
==》* 表示该类型是一个指针
==》变量名称则用于存储地址的值。
2 “&”用以获取一个变量的地址,“ * ”取出一个地址内的值
px+n指针向下偏移一个单元,不改变指针的值,
px++改变指针的值
注意:数组名称是常量,不能赋值(++用的时候会报错)
if(pa = NULL) :pa变量赋值,且值为假,不执行
if(pa == NULL):逻辑判断,看pa内部是不是为空
3.指针初始化
char * pc = NULL;
作用 避免野指针,没有任何初始化的指针。
指针的变量地址初始化: char *pc = &c;
用其他指针初始化: char *pc = &c;
用绝对地址初始化:char *pc = 0x23423423; 注意:该地址必须是可以访问的地址。一般不建议采用
5.数组与指针
- 相同点啊a[i] = pa[i]
(pa + i) =(a+i)
a[i] = pa[i] = *(pa+i) = *(a+i);
数组名称是一个指针常量,不允许改变。
pa指针是指针变量,可以随时修改。
char buff[] ="aasdfadsf"; ===>buff是本地内存
137 char *pa = &buff[0]; ==>pa 指向本地内存,可以修改。
138 char *pb = "asdfadf"; ==>pb 指向静态常量区数据,不允许修改。
char buf[5] = {"a,b,c,d,e,f};
char *p = "a,b,c,d,e,f"
区别: 记住所有带双引号的字符串都存储在静态常量区,前者可操作,后者不可操作,因为前者是把字符常量区的字符串拿到了栈区,变成了可操作数,而后者是直接定义了一个指针,指向了文本区,所有静态常量区的都是只读的!!!
面试题:
141 int main()
142 {
143 int a[5]= {1,2,3,4,5};:
144 int *p = (int *)(&a+1);
145 printf("%d %d \n",*(a+1),*(p-1));
146 }
打印结果 2,5
*(a+1) :首地址向下偏移一个int类型单位,到了a[1]的位置
(&a+1) :&a为取数组名的地址,即为整个数组的地址,它的类型为数组类型,指针偏移到数组后面的元素上-1刚好到数组最后一个元素即5
练习题:
1、输入一行文字,找出其中大写字母,小写字母,空格,数字以其他的字符各有多少
int main(int argc, char *argv[])
{
char buf[N] = {0};
char * pf = &buf[0];
int da = 0,xiao = 0,kong = 0,num = 0,other = 0;
printf("请输入字符串以检测\n");
gets(pf);
printf("%s\n",pf);
while(*pf != '\0')
{
if(*pf >= 'A' && *pf <= 'Z')
da++;
else if((*pf >= 'a') && (*pf <= 'z'))
xiao++;
else if(*pf == ' ')
kong++;
else if((*pf >= '0') && (*pf <= '9'))
num++;
else
other++;
pf++;
}printf("大写字母;%d\n小写字母:%d\n空格:%d\n数字%d\n其他%d\n",da,xiao,kong,num,other);
return 0;
}
2、输入一个字符串,用指针求出字符串的长度。
int main(int argc, char *argv[])
{
char buf[N] = {0};
char * pf = &buf[0];
int count = 0;
printf("请输入字符串以检测\n");
scanf("%s",pf);
while(*pf++ != '\0');
printf("%ld\n",(long int)pf-(long int)&buf[0]-1);
return 0;
}
3、 main()
{
int a[5]={1,2,3,4,5};
int ptr=(int )(&a+1);
printf("%d,%d",(a+1),(ptr-1));
}
输出结果是什么?
2,5,上面概念处讲过了
4、请问以下代码有什么问题:
int main()
{
char a;
char *str=&a;
strcpy(str,“hello”);
printf(str);
return 0;
}
main函数内部第一行和第三行冲突,定义的是一个字符变量,而非一个字符串常量
5、 char* s=“AAA”;
printf("%s",s);
s[0]=‘B’;
printf("%s",s);
有什么错?
第一行的意思为把字符串常量存放在静态常量区,不可修改
6、编写一个程序实现功能:将两个字符串合并为一个字符串并且输出,用指针实现。
char str1[20]={“Hello ”}, str2[20]={“World ”};
int main(int argc,char *argv[])
{
char str1[20] = {"Hello"};
char str2[20] = {"World"};
char *p1 = str1;
char *p2 = str2;
while(*p1 != '\0'){
p1++;
}
//p1--;
while(*p2 != '\0'){
*(p1++) = *(p2++);
}
*p1 = '\0';
p1 = str1;
p2 = str2;
printf("str1 = %s\nstr2 = %s\n",p1,p2); //在main函数的时候,不可以拿p1,p2直接打印值,重新定义一个函数就可以?
???
return 0;
}
7、编写一个程序实现功能:将字符串”Computer Secience”赋给一个字符数组,然后从第一个字母开始间隔的输>出该串,用指针完成。
int main(int argc,char *argv[])
{
char src[128] = {"Computer Secience"};
char dest[128] = {0};
char *ps = src;
char *pd = dest;
while(*ps != '\0'){
*pd++ = *ps++;
*pd++ = ' ';
}
printf("dest = %s\n",dest);
return 0;
}
8、使用C语言实现字符串中子字符串的替换
描述:编写一个字符串替换函数,如函数名为 StrReplace(char* strSrc, char* strFind, char* strReplace)>,strSrc为原字符串,strFind是待替换的字符串,strReplace为替换字符串。
举个直观的例子吧,如:“ABCDEFGHIJKLMNOPQRSTUVWXYZ”这个字符串,把其中的“RST”替换为“ggg”这个字符串,>结果就变成了:
ABCDEFGHIJKLMNOPQgggUVWXYZ
void StrReplace(char * strSrc,char *strFind,char *strReplace)
{
char *ps = strSrc;
char *pf = strFind;
char *pr = strReplace;
char cat[128] = {0};
char *pc = cat;
char *p1 = NULL;char *p2 = NULL;char *p3 = NULL;
while(*ps++ != '\0')
{
if( (*(ps) == *(pf)) &&
(*(ps+1) == *(pf+1)) &&
( *(ps+2) == *(pf+2) ))
{
#if 0
p1 = ps;
while(*p1 != '\0')
{
*pc++ = *p1++;
}
#endif //这段没作用
#if 0
*ps = *pr;
*(ps+1) = *(pr+1);
*(ps+2) = *(pr+2);
printf("find it\n");
#endif
while(*pr != '\0')
{
*ps++ = *pr++;
}
}
}
strcat(cat,strSrc);
}
int main(int argc,char *argv[])
{
char src[128] = {"ABCDEFGHIJKLMNOPQRSTUVWXYZ"};
char dest[128] = {"RST"};
char place[128] = {"ggg"};
printf("替换前:%s\n",src);
StrReplace(src,dest,place);
printf("替换后:%s\n",src);
return 0;
}