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