天天看点

传说中的大山-指针

总有人说c语言的三座大山及,指针,函数,数组,在学习当中给我们带来了很大的困扰,对抽象问题无法理解,好,很高兴我翻越了其中一座山,接下来我会分享这三个问题的学习方法,每个章节后面都会附有练习题,需要着重强调的是,题一定要自己想办法敲一下,对概念的理解和发现问题有很大的帮助,好了,祝大家尽快渡过难关!!!

  1. 指针的定义:

    格式: <存储类型> <数据类型> * 变量名称;

    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;
}   
           

继续阅读