精华内容
下载资源
问答
  • 指针高级应用 指针指针:用于存放指针变量的地址 type **name; 函数指针指针函数 函数指针:int *f(int x); 指针函数: int (*p)(); 区别:函数指针本质是一个指针指针函数本质是一个函数,返回值是一个地址。...

    指针高级应用

    • 指针的指针:用于存放指针变量的地址
      type **name;
    • 函数指针与指针函数
      函数指针:int *f(int x);
      指针函数: int (*p)();
      区别:函数指针本质是一个指针;指针函数本质是一个函数,返回值是一个地址。
    • 无类型指针
      定义: void *p;
      可以将任意类型的指针赋给无类型指针,但不能将无类型指针赋给其他类型指针,如若要赋值必须进行强转。
    • const限定符
      指向常量数据的指针:const int *p;
      常指针:int * const p;
      两者区别:常指针的值不可以修改,但指向的内容可修改;指向常量数据的指针,其值可以修改,但指向的内容不可修改。

    指针实现结构体中数据的增删改

    结构体定义

    typedef struct staff
    {
      char username[20];
      char password[20];
      char role[20];
      int flag;
    }STAFF_T;
    STAFF_T staffs[50] = {
          {"admin" ,"123456","admin"},
    	  {"manage" ,"123456","manage"},
    	  {"waiter" ,"123456","waiter"}
    };
    

    添加用户

    void Staff_Add( STAFF_T  *people)//用户添加
    {
    	STAFF_T newple;
    	char name[20];
    	char pwd[20];
    	char role[20];
    	int i;
    	printf("----------------->>>-------------------\n");
    	printf("用户添加");
    	printf("\n请输入账号:");
    	scanf_(name,12,2,0);
    	printf("\n请输入密码:");
    	scanf_(pwd,8,1,1);
    	printf("\n用户身份:");
    	scanf_(role,12,2,0);
    	strcpy(newple.username,name);
    	strcpy(newple.password,pwd);
    	strcpy(newple.role,role);
    	people[count++] = newple;
    	printf("\n添加成功!\n");
    }
    

    修改用户信息

    void Staff_Modify(STAFF_T  *people)//修改员工信息
    {
    	STAFF_T newple;
    	int i;
    	char name[20];
        char pwd[20];
    	char role[20];
    	printf("----------------->>>-------------------\n");
    	printf("修改员工信息");
    	printf("\n请输入要修改的用户名:");
    	scanf_(name,12,2,0);
    	for(i = 0;i<count;i++)
    	{
    		if(strcmp(people->username,name) == 0)
    		{
    			
    			printf("\n请输入账号:");
    			scanf_(name,12,2,0);
    			printf("\n请输入密码:");
    			scanf_(pwd,8,1,1);
    			printf("\n用户身份:");
    			scanf_(role,12,2,0);
    			strcpy(newple.username,name);
    			strcpy(newple.password,pwd);
    			strcpy(newple.role,role);
    			people[i] = newple;
    			printf("\n修改成功!");
    		}
    		else if(i>=count-1)
    		{
    			printf("\n该用户不存在!");
    		}
    		people++;
    	}
    }
    

    遇到问题

    1.关于函数指针、指针函数,指向常量数据的指针、常指针还是有一点绕,课上听得有点云里雾里。要想理解的更加透彻,还需要之后多通过练习去理解这几者之间的得区别。
    2.在员工信息的增删改中,使用指针去实现增删改,刚开始对指针的使用还是有点混乱,后面经过老师的指点,再加上自己后面的练习慢慢理解了这其中的使用方法。

    心得体会

    指针的学习也告一段落了,这几节指针的课程学起来明显比之前更费点力,现在理解的还不是那么地透彻,后面我会通过更多的指针方面的练习去加强自己对指针的理解。

    展开全文
  • 1.指针与字符数组 /** 定义字符串的2种方式 * 1.利用数组 * char name[] = "itcast" * *特点:字符串里面的字符是可以修改的 * *使用场合:字符串的内容需要经常修改. * 2.利用指针 * char *name = "itcast";...

    1.指针与字符数组

    <span style="font-size:14px;">     
        /**  定义字符串的2种方式
         *   1.利用数组
         *    char name[] = "itcast"
         *    *特点:字符串里面的字符是可以修改的
         *    *使用场合:字符串的内容需要经常修改.
         *   2.利用指针
         *    char *name = "itcast";
         *    *特点:字符串其实是一个常量字符串,里面的字符是不能修改的;
         *    *使用场合:字符串内容不需要修改,而且这个字符串经常使用.
         </span>

    2.指针与字符串数组

    <span style="font-size:14px;">   /** 定义字符串数组
         *  1.指针数组(字符串数组)
         *  char *name[] = {"jack", "rose"};
         *  2.二维字符数组(字符串数组)
         *  char name[2][10] = {"jack", "rose"};
         */
    
    </span>
    3.返回指针的函数

    <span style="font-size:14px;"> 
    
        char *test();//声明,(char *)
        char *test(){
            return "hehe";
        }
        char *name = test();
        printf("name = %s",name);
      
       </span>

    4.指向函数的指针 void  (*p)();

     (*p)是固定写法,代表指针变量将来肯定指向函数.

     左边的void:指针变量p指向的函数没有返回值.

     右边():指针变量指向的函数没有参数.

    <span style="font-size:14px;">    
    
     /*
        void test(){
            printf("xiaozhang");
        }
        
        void (*q)();
        p = test;//指针变量p指向了test函数
        (*p)();利用指针变量间接调用函数.//相当于test();直接调用函数.
        //或者用次方法 p(); //p = test;上面
     */
    
    </span>
    例如:

    <span style="font-size:14px;">    
        int sum(int a, int b);
        int (*q)(int, int);//int (*p)(int a,int b);定义了一个指向函数的sum的指针.
        q = sum;//将指针变量p,指向函数sum
        int c = (*q)(10, 11);//三种方式相同.
        // int c = q(10, 11);
        //int c = sum(10, 11);
        printf("%d \n",c);//21</span>

    5.char *p[n]  与  char (*p)[n]的区别  

    <span style="font-size:14px;">    /*
        char str[6][10] = {};
        char (*p4)[10] = str;
        char *p5[10];
        printf("%lu \n",sizeof(*p4));//10
        printf("%lu \n",sizeof(p4));//8
        printf("%lu\n",sizeof(p5));//80
        printf("%lu",sizeof(*p5));//8
        */
         /*
        char str[6][10] = {};
        char (*p4)[10] = str; // *p4为char[10]型,相当于str[6].指针加一,将增加10个字节的长度:sizeof(*p4):10
        char *p4[10];//指针数组,有十个元素,每个元素指向char类型变量的指针
        sizeof(p4):10*8=80
         */
    
    </span>
    6.实参到形参的传递,是一个拷贝的过程,传递有两种方式:

          1.传值.传递的时变量中的内容.函数内部改变不会影响外部的变量.

          2.传地址.传递的是变量的地址,函数内部改变会影响外部的变量.

           例:两个数的最大值(传值两个数的和(传值给数组进行赋值(传地址)

    7.p++与p + 1的区别

         p++;   会改变p中存储的地址,指针重指向.

         p + 1  不会改变p的地址.依然指向数组的首地址.

    8.指针与结构体

    <span style="font-size:14px;">   
        //指针与结构体的关系.
        Student stu = {"xiaozhang", 18, 60.0};
        printf("%s\n", stu.name);
        
        Student *p = &stu;
        //如何通过结构体指针变量访问结构体成员.
        //结构体指针变量->结构体指针
        printf("%s ,%.1f , %d\n", p->name, p->score, p->age);
        
    
    </span>
    9.指针与结构体数组
    <span style="font-size:14px;">Student stu[5] = {
            {"hehe", 21, 78.0},
            {"haha", 22, 45.8},
            {"hiahia", 24, 64},
            {"heihei", 23, 56.0},
            {"heihi", 28, 67.0}
        };
    
        (p + 3)->name = "duck";
        p[2].age = 50;
        p[1].score = 59.9;
        (*(p+3)).name = "duck"
    
    
    </span>
    10.练习:取出字符串中的数字

    方法1:这种方法用到strcpy存在bug

    <span style="font-size:14px;">   
     char b[30] = "sdfgdg12sd12gd2132432fsg";
        //
        char *p = b;
        printf("%s\n",b);
    //    int i = 0;  
    //    while (p[i] != '\0') {
    //        if (p[i] >= '0' && p[i] <= '9') {
    //            //p = p + 1;
    //            strcpy(p + i, p + i + 1);
    //            i--;
    //        }
    //        i++;
    //    }
    //    printf("%s",p);
        
        //或者
        while (*p != '\0') {
            if (*p >= '0' && *p <= '9') {
                //p = p + 1;
                strcpy(p, p + 1);
                p--;
            }
            p++;
        }
        printf("%s",b);
    
    </span>
    方法2:
    <span style="font-size:14px;"> 
    
        char b[]={"adsddddfff65565665dd4s"};
        char *p = b;                    //p指向a[0]
        int k=0;                        //记录字符串中数字的个数
        for (int i = 0; i < sizeof(b); i++) {
            if (*p >= '9' || *p <= '0') {       //判断是不是字符,是字符则执行
                if (k!=0) {
                    *(p - k) = *p;                 //将数字后的字符付给最前面的数字所在的位置
                    *p='\0';                   //将前移的字符所在的位置付成\0
                }
                p++;                           //指针前移
            }else  if('0' < *p && *p < '9'){
                k++;
                p++;                           //指针前移
            }
        }
        printf("%s",b);
        
    
    </span>

    11.const 用法 : const 安全性修饰的变量是readonly,只能读取数据,不能修改.

    const面试题:

    <span style="font-size:14px;">    /**
         * p 是指针变量,存储p地址
         * *p 是指向变量指向的空间,也就是变量a的空间
         *
         *  面试题:请问const修饰的谁不可变?
         * 1.const int *p = &a;//修饰*p,即*p不可变,不能通过指针变量p修改指向空间的内容,但是指针变量p可以重新赋值,重指向.
         *  测试1: *p = 10; p = &b;
         * 2.int const *p = &a;//修饰*p,即*p不可变,不能通过指针变量p修改指向空间的内容,但是指针变量p可以重新赋值,重指向.
         *  测试2: *p = 10; p = &b;
         * 3.int * const p = &a;//修饰p,即p不可变,能通过指针变量p修改指向空间的内容,但是指针变量p不可以重新赋值,不能重指向.
         *  测试3: *p = 30; p =&a;
         * 4.const int * const p = &a;//修饰*p以及p ,都不可以改变,不能通过指针变量p修改指向空间的内容,指针变量p也不可以重新赋值,不能重指向.
         *  测试4: *p = 10; p =&a;
         *
         */</span>

    展开全文
  • 高级指针应用

    2018-03-12 20:06:17
    【摘要】指针作为C语言阶段最重要的部分,连接着...在之前的一篇博客中,我把指针的初级使用整理到一起,最近又学了些关于高级指针的知识,我也照例总结出来,希望会对你们有所帮助。 目录 1.指向指针的指针以及...
    
    

    【摘要】指针作为C语言阶段最重要的部分,连接着C语言和数据结构,指针的出现,简化了代码,使得程序猿从大量的代码中解脱出来。但是随之而来的也是各种副作用。因此,你必须完全熟悉它,才可以利用好它来帮助自己。在之前的一篇博客中,我把指针的初级使用整理到一起,最近又学了些关于高级指针的知识,我也照例总结出来,希望会对你们有所帮助。
     目录
         1.指向指针的指针以及多级指针的运用
         2.指针的高级声明(重点描述)
         3.函数指针
         4.字符串常量
         
    一.指向指针的指针以及多级指针的运用
            在讲这个知识点的时候,我觉得我应该把我之前遇到的一个问题给你们也看一看,当然我会把正确的结果也写出来 
         单看这个问题,你肯定可以很轻易的就得到这个答案,但是,如果稍微变一下呢
           我只是把第五行改了一下,你觉得输出的结果会是什么呢?这次你可能就会犹豫一会了,但是我告诉你,答案和上面的一样。接下来我解释一下为什么是这样,这也是我当初想不通的地方
        在第一个例子中,我定义了一个一级指针和一个二级指针,这两个指针一个存储变量 i 的地址,一个存储指针 pi 的地址,所以,一级指针解引用就是变量 i 的值,二级指针进行两次解引用也就是变量 i 的值,这个可以用一个图片来表示
    通过这幅图,我们就可以很好地解释答案了
            但是,第二个例子中,我没有定义二级指针,我只是定义了一个一级指针 ppi ,在 = 号的右边 ,是 & *pi,由于指针作为右值,就是一个地址常量,这个地址就是指向i的地址,所以再进行 & 之后,就是 i 的值,所以说,指针 pi 和指针 ppi 指向的都是 i 的地址,所以值是不变的。
           指针可以进行多次定义,也可以进行多次间接访问,但是在一般的程序中,最多会碰到二级指针或者三级指针,如果遇到了更高阶的,我们也不用害怕,只要清楚它所指向的内容就可以准确的得到它的值
           
    int i=10;
    int *pi=& i;
    int **ppi=& pi;
    int ***pppi=& ppi;
        别看定义了三阶指针,其实也不难,因为他们指向的都是前一个指针的地址,所以最后的结果都是10
    二.指针的高级声明
           要想搞清楚指针的高级声明,我想先给你看一些不同的声明,你看你能说对几个,我那时候刚看到真是错了好多
     这里面就涵盖了指针高级声明的大多数。其中我认为比较难理解的就是倒数第二个,那我就把倒数第二个进行详细说明一下吧
       int (*f[ ])( ) ,首先可以确定的是 f 一定是一个数组,*f[ ] ,那么数组里面的元素一定是整型指针类型的,然后第二个括号表明了 f 的身份是一个函数,所以整体理解起来就是 有一个 数组,里面存放的数据类型是函数指针 ,f 所指向的函数的返回值是int型
    三.函数指针
            对于函数,我们已经不陌生了,但是对于函数指针,我们了解的或许还很少,但是既然它也是一个指针,那他的一些用法还是和普通指针很类似的。、
      1. 对函数指针进行间接访问时一定要进行初始化,让它指向某个函数。
       int   (*pf)(int )= &f;
      这里就对 pf 进行了初始化,让它指向了函数 f
          有一条要说的就是,函数名在被使用时编译器总会把它转换为指针函数,所以 & 符号可以加上也可以不加
      2.通过使用函数指针,你可以实现回调函数,一个指向回调函数的指针作为参数传递给另一个函数
      四.字符串常量
            字符串常量有别于普通字符串的最大区别在于,普通的字符串是放在数组里面的,因此已经提前开辟好了空间将字符串挨个的放进去,但是字符串常量通常是放在只可读区,而通常有一个指针指向这个位置,所以字符串常量本身并没有存储空间,,它只是一个指针常量,也就无法进行修改。
           既然是指针,那么我们也可以用下标引用,间接访问以及指针运算,所以,看看下面几种情况,你知道是什么意思吗?
       1.  "xyz"+1
         因为定义的是一个字符串常量,因此本质上就是一个指针,对指针加 1  ,就是让它指向第二个字符,也就是指向 y 
        2.  *"xyz"
         因为字符常量类型是“指向字符的指针”,所以这个间接访问的结果就是它所指向的字符 x ,可不是整个字符串啊,不要把两个搅混了
        3. "xyz"[2]
         下标本质上和指针的  *没有区别,即让指针向后移两位,指向第三个字符 z
        4. *("xyz" +4)
        偏移量已经超过了字符串的范围,所以最终的值是一个不可预测的字符
        

    展开全文
  • 指针高级应用.txt

    2021-03-15 11:21:01
    指针高级应用.txt
  • C语言指针高级应用

    2021-02-01 15:49:51
    指针高级应用指针数组与数组指针字面意思来理解指针数组和数组指针分析指针数组和数组指针的表达式函数指针与typedef函数指针的实质(还是指针变量)函数指针的书写和分析方法typedef关键字的用法 指针数组与数组...

    指针数组与数组指针

    字面意思来理解指针数组和数组指针

    1.指针数组的实质是一个数组,这个数组中存储的内容全部是指针变量。
    2.数组指针的本质是一个指针,这个指针指向的是一个数组。

    分析指针数组和数组指针的表达式

    int p[5]; int (p)[5]; int *(p[5]);
    一般规律,int p是一个指针。 int p[5]是一个数组。
    总结:我们在定义一个符号时,关键在于:首先要搞清楚你定义的符号是谁(第一步:找核心),其次再来看谁跟核心最近、谁跟核心结合(第二部:找结合);以后继续向外扩展(第三步:继续向外结合直到整个符号完)。
    如果核心和
    结合,那么核心是指针。如果核心和[]结合,那么核心是数组。如何核心和()结合,那么核心是函数。
    那么很好判断第一个表达式是指针数组,第二个表达式是数组指针,第三个也是指针数组。
    注意:符号的优先级的用处是决定当两个符号一起作用的时候决定哪个符号先运算,哪个符号后运算。遇到优先级问题第一种方法是查询优先级表,第二种方法是自己记住,只需要记住 [] . ->这三个优先级比较高就好了。
    关于分析C语言复杂表达式的总结:
    1.优先级和结合性是分析符号意义的关键,在分析C语言的问题时,不要胡乱去猜测规律,不要总觉得C语言无从捉摸,从已知的规律出发按照既定的规则去做即可。
    2.学会逐层剥离的分析方法,找到核心后从内到外逐层进行结合,结合之后可以把已经结合的部分当做一个整体,再去和整体外面的继续进行结合。
    3.基础理论和原则是关键,没有无缘无故的规则。

    函数指针与typedef

    函数指针的实质(还是指针变量)

    1.如何函数指针的实质还是指针,还是指针变量。本身占四字节(在32位系统中,所有的指针都是4字节)
    2.函数指针,数组指针,普通指针之间并没有本质区别,区别在于指针指向的东西是什么类型。
    3.函数的实质是一段代码,这一段代码在内存中是连续分布的,(一个函数的大括号括起来的所有语句将来编译出来生成的可执行程序是连续的),所以对函数来说很关键的就是函数中的低语句代码的地址,这个地址就是所谓的函数地址,在C语言中用函数名这个符号来表示。
    4.结合函数的实质,函数指针其实就是一个普通变量,这个普通变量的类型是函数指针变量类型,他的值就是某个函数的地址(也就是他的函数名这个符号在编译器中对应的值)。

    函数指针的书写和分析方法

    1.C语言本身是强类型语言(每个变量都有自己的变量类型),编译器可以帮我们做严格的类型检查。
    2.所有的指针变量类型其实本质都是一样的,但是为什么在C语言中要取区分他们,写法不一样呢(比如int类型的指针就写作 int p;数组指针就写作int (p)[5];函数指针就写的更复杂)
    3.假设我们有个函数是: void func(void); 对应的函数指针:void (p)(void);
    类型是 void (
    )(void);
    4.函数名和数组名的最大区别就是,函数名做右值时加不加&效果和意义都是一样的;但是数组名做右值时加不加&意义就不一样了。数组名a做右值代表数组第一个元素的地址,&a代表整个数组的首地址,在参与运算的时候会有区别。
    5.写一个复杂的函数指针的实例: char *strcpy(char *dest ,const char *src);
    对应的函数指针就是: char (pfunc)(char *dest,const char *src);
    函数原型是: char ()( char *, const char * );

    typedef关键字的用法

    1.typedef是C语言中一个关键字,作用是用来定义(或者叫重命名类型)。
    2.C语言的类型一共有两种,一种是编译器定义的原生类型(基础数据类型,如int、double之类)。第二种是用户自定义类型,不是语言自带的是程序员自己定义的(比如数组类型、结构体类型、函数类型等)。
    3.数组指针、指针数组、函数指针等都属于用户自定义类型。
    4.有的时候自定义类型太长了,用起来不方便,就用typedef来给他重命名一个短点的名字。
    5.注意:typedef是给类型重命名,也就是说typedef加工出来的都是类型,而不是变量。

    展开全文
  • 指针高级应用

    2014-07-07 17:25:06
    有关于C语言指针高级应用,帮助初学者更好地理解和应用指针
  • 高级指针概念和应用

    千次阅读 2016-05-01 21:28:54
    一:数组指针指针数组的理解: 1.首先我们从一个例子开始讲起 include int main() { int a[5][5]={0};//创建一个二维整型数组,并初始每个元素化为0; int(*p)[4]=NULL;//定义一个数组指针,这个指针指向...
  • 四、指针高级应用总结 1 笔试积累 指针数组本质是数组,数组元素全为指针。 数组指针本质是指针,指向的是一个数组。 typedef的意义在于简化书写和创造平台无关性。 typedef重定义的类型不会原地展开,也...
  • 高级指针

    2018-01-08 01:45:28
    在学习C语言过程中,指针的使用是必不可少的,下面我们来简单的对一些高级指针做一些介绍以及应用。 一、指针数组 指针数组是一个数组,是用来存放指针的数组,来看下面一段代码#define _CRT_SECURE_NO_WARNINGS 1...
  • 《4.4.C语言复杂表达式与指针高级应用》 目录 第一部分、章节目录... 1 第二部分、章节介绍... 1 第三部分、随堂记录... 2 4.4.1.指针数组与数组指针... 2 4.4.1.1、字面意思来理解指针数组与数组指针... 2 ...
  • c语言高级指针理解及应用(上)

    千次阅读 2017-12-01 15:16:22
    6.指针应用的一些代码**本文先说明一些指针的概念及一些简单应用,更详细的将在(下)说明正文开始指针的基础知识什么是指针以下来自百度百科:指针,在计算机科学中,指针(Pointer)是编程语言中的一个对象,...
  • 本章主要介绍c语言指针中,指针和数组的对应关系,指针应用如数组指针指针数组,函数指针,函数指针数组等比较难以理解的内容,本人希望能结合我在学习中遇到的问题用通俗易懂的语言给大家介绍这些知识,若有...
  • 指针高级应用(二)

    2017-12-16 11:03:05
    2017-8-2 指针高级应用(二) 完成复习时间2017-8-2 9点 学习的知识点: 1、指针指针:int **pint;//二级指针存一级指针地址,方便改变一级指针; 2、函数指针: typedef int (*pfun)(int,int);//代表定义一个返回值...
  • 指针高级应用

    2015-01-10 23:01:21
    要求使用指针数组进行处理。 // char array[6][10] = {"apple","iphone","ipad","iWatch","macBook","iphone6"}; // rankString(array);   // 1. (**) 写一个函数交换两个结构体变量 /...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,231
精华内容 492
关键字:

高级指针应用