【学习ios之路:C语言】②高级指针应用

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>
时间: 2024-10-17 18:15:08

【学习ios之路:C语言】②高级指针应用的相关文章

【学习ios之路:C语言】指针

指针 1.指针定义,即简单用法. <span style="font-size:14px;"> //指针变量:专门用来存储地址的变量. int *p = NULL;//NULL == 0 /** * 变量定义时: * (int *):指针类型 * p: 变量名 NULL:初始值. * NULL(指向了一个无效的区域) * *的作用: 告诉编译器,后面变量是指针变量,用来存储地址. * int作用: 1.当通过指针变量取数据时,一次性读取几个字节的数据. 2.当指针变量+1时

【学习ios之路:C语言】指针函数

指针函数int max(int a, int b); *   函数指针:指向一个函数的指针变量.' *   函数的类型:返回值类型+参数 *   函数指针变量类型: int (*)(int x, int y) *   指针变量的名字:max *   初始值:NULL *   max 可以指向一个返回值是int型并且有两个int型的参数的函数. 应用:学生结构体按照姓名,年龄,分数升序排序 1.函数的声明 typedef struct student{ char name[20]; int age

【学习ios之路:C语言】C语言中容易出错的试题整理.

注:此类题都是比较基础的试题,但是都容易让人忽视,或者平常不在意的. 1.表达式3.6-5/2+1.2+5%2的值是(D). A. 4.3  B. 4.8  C.3.3  D. 3.8 2.设有说明:char w;int x;float y;double z;则表达式w*x+z-y值的数据类型为:(D) A. float   B. char  C. int  D. double 3.以下关于运算符优先顺序的描述中正确的是:(C) A.关系运算符<算术运算符<赋值运算符<逻辑与运算符  

【学习ios之路:C语言】总结整理:学好Object-C---C语言必备知识点

一.基本数据类型.常量.变量.运算符 1.数据类型 int. short.char.long.float.double. 2.常量的分类.(1).整型常量 (2)浮点型常量 (3)字符常量 (4)字符串常量. 3.常量的特性:常量存储在常量区,常量区的内容不可被更改. 4.变量的定义与本质.数据类型 变量名 = 初值 . 本质变量就是一个容器. 5.变量名的命名规范 6.运算符. (1)赋值运算符 = (2)算数运算符 +  -  *  /  %  ++  -- (3)复合运算符  +=  -+

【学习ios之路:C语言】存储区内存划分

一. 内存存储区的划分: 1.栈区:栈区主要存放函数内部定义的变量,数组.函数调用时,开辟空间,函数执行完毕,回收空间,空间的开辟与回收有系统管理. 2.堆区:堆区最大的特点:空间的开辟与释放有开发人员手动管理. 3.全局区静态区:主要存放函数外部定义的全局变量以及静态变量,空间一旦开辟,就不会回收.直到应用程序执行结束. 4.常量区:存储常量.1.整形常量.2.浮点型常量.3,字符串常量.4.字符串常量. 5.代码区:存放程序编译之后生成的cpu指令. 二.malloc,在堆区开辟空间. //

【学习ios之路:C语言】循环方面试题

1.打印出如下所示图形  : * *  * * * * 代码如下: for (int i = 0; i < 3; i++) { for (int j = 2; j > i; j--) { printf(" "); } for (int k = 0; k < i + 1; k++) { printf(" *"); } printf("\n"); } 2. 打印出如下图形: * *   * *  *  * *   * * 代码如下:

【学习ios之路:C语言】一维数组,数组排序,字符数组

1.数组 数组,快速定义多个变量. 数组定义: 数据类型 数组名[数组元素的个数] = {值1, 值2, 值 3}; 数组所占存储空间大小 = 数组元素个数 * 每个元素所占的存储空间大小. %lu  unsigned long 无符号的长整型. 无符号 >=0 sizeof 存储大小值  //用来计算一个变量,类型,以及数组所占存储空间的大小. int a[5] = { 2, 7, 4, 3, 6 };  printf("%lu\n", sizeof(arr)); //5 in

【学习ios之路:C语言】进制.位运算.栈

1.进制转换 1).10进制转为N进制.方法:(连除倒取余). 2).N进制转换为10进制.方法:(按权求和法):当前位上的数乘以基数的位数减1次方. 例: 0b1111 ---- 1* 2^3 + 1*2^2 +1 * 2^1 +1*2^0 = 15; 038 ----- 3*16^1 +8*16^0 = 56; 3).N进制转换N进制. 例如: 二进制 --- 16进制 1010   0011  ----  A 3 1111   0011  ----  F 3 int a = 010;//8

【学习ios之路:C语言】小程序:实现类似ATM取款机功能.

小程序:模拟ATM机取款的过程 1).定义两个能保存5个整形数的数组,一个用于保存5个人的卡号,一个用于保存对应卡号的密码 2).判断输入的卡号是否在数组中. 3).如果在数组中就让输入密码,判断是否和卡号对应的密码匹配. 4).判断密码,24小时内只允许输入3次错误的密码.输入错误应该提示还剩下的输入次数,3次都输入错误提示24小时内不允许操作该卡. 5).密码正确就让用户对该账户进行相应的操作. 6).注意取款的限制. 7).述功能对于一个ATM机是循环的过程,也就是说每个客户都会按照上面的