9 指针与字符串2

来源:互联网 发布:点点财富网络借贷 编辑:程序博客网 时间:2024/05/22 12:08

9 指针与字符串2


1 指针使用

  • 指针的应用:1、函数返回多个值,某些值只能通过指针返回。传入的参数实际上是需要保存带回的结果的变量;2、函数返回运算的状态,结果通过指针返回,常用的套路是让函数返回特殊的不属于有效范围内的值表示出错,例如0、-1等。但是任何数值都是有效时,必须分开返回。
    • 交换两个变量:
void swap(int *pa, int *pb){    int t = *pa;    *pa = *pb;    *pb = t}
  • 传入函数的数组int a[]成了什么?函数参数中的数组其实是int*,sizeof返回4,它变成了指针。如果改成int *a 依然可以编译运行成功。
  • 函数参数表中的数组是指针。sizeof(a) = sizeof(int *)。但是可以用数组的运算符[]进行运算。
  • 下面四种函数原型等价:
    • int sum(int *ar, int n);
    • int sum(int *, int);
    • int sum(int ar[], int n);
    • int sum(int [], int);
  • 数组变量是特殊的指针。

    • 数组变量本身表达地址,所以:
      • int a[10]; int *p = a; 无需用&取地址
      • 但是数组的单元表达的是变量,需用&取地址
      • a == &a[0]
    • []运算符可以对数组做,也可以对指针做:
      • p[0] 等价于 a[0]
    • *运算符可以对指针做,也可以对数组做:
      • *a = 25;
    • 数组变量是const的指针,所以不能被赋值
  • 指针是const:

    • 表示一旦得到了某个变量的地址,不能再指向其他变量
  • 所指是const:
    • 表示不能通过指针去修改这个变量,但是这个变量依然可以变
int i;const int* p1 = &i;  //变量不能通过指针修改int const* p2 = &i;  //变量不能通过指针修改int *const p3 = &i;  //指针不能被修改
  • 当要传递的参数的类型比地址大的时候,这是常用的手段:既能用比较少的字节数传递值给参数,又能避免函数对外面的变量的修改。
  • const int a[] = {1,2,3};
    • 数组变量已经是const的指针了,这里的const表示数组的每个单元都是const int,所以必须通过初始化进行赋值。
  • 因为把数组传入函数时传递的是地址,所以函数内部可以修改数组的值。为了保护数组不被函数破坏,可以设置参数为const

2 指针运算

  • char,指针加1地址加1;int,指针加1地址加4
  • 给指针加1表示让指针指向下一个变量,如果指针不是指向一片连续分配的空间,如数组,则这种运算没有意义。
  • *p++:取出p所指的数据,再把p移到下一个位置,常用于数组类的连续空间操作。
  • 0地址:

    • 内存中有0地址,但是0地址通常是个不能随便碰的地址,所以指针不应该具有0值
    • 用0值做特殊的事情:
      • 返回的指针无效
      • 指针没有被真正初始化(先初始化为0)
    • NULL是个预先定义的符号,表示0地址
      • 有的编译器不愿意你用0表示0地址
  • void*表示不知道指向什么东西的指针,计算时与char*相同

  • 指针也可以转换类型:int*p = &i; void *q = (void*)P;
  • 用指针做什么?

    • 需要传入较大的数据时用做参数
    • 传入数组后对数组操作
    • 函数返回不止一个结果
    • 动态申请内存
  • C99可以用变量做数组定义的大小

  • malloc大小以字节为单位,返回类型为void*,free只能还申请来的空间的首地址
include<stdlib.h>int *a = (int*)malloc(n*sizeof(int));free(a);

3 字符串操作

  • int putchar(int c);
    • 向标准输出写一个字符
    • 返回写了几个字符,EOF(-1)表示失败,end of file
  • int getchar(void);
    • 从标准输入读入一个字符,返回类型是int为了返回EOF(-1)
    • windows-ctrl+Z,unix-ctrl+D
  • 键盘和屏幕中间有一个shell,用户输入是给shell填缓冲区,getchar和scanf只是在缓冲区读东西。

  • char **a;

    • a是一个指针,指向另一个指针,那个指针指向一个字符(串)
  • char a[][10];
    • a是二维数组,第二维需要确定的数值
  • char *a[];

  • 程序参数:

int main(int argc, char const *argv[])

argv[0]是命令本身


4 字符串函数

  • strlen:返回字符串长度
size_t strlen(const char *s);int mylen(const char *s){    int idx = 0;    while(s[idx] != '\0'){        idx++;    }    return idx;}
  • strcmp:比较字符串,返回0(s1==s2),1(s1>s2),-1(s1
int strcmp(const char* s1, const char *s2);int mycmp(const char* s1, const char* s2){    int idx = 0;    while(s1[idx] == s2[idx] && s1[idx] != '\0'){        idx++;    }    return s1[idx] - s2[idx];}int mycmp(const char* s1, const char* s2){    while(*s1 == *s2 && *s1 != '\0'){        s1++;        s2++;    }    return *s1 - *s2;}
  • strcpy:把src的字符拷贝到dst,restrict表明src和dst不重叠,返回dst
char *strcpy(char *restrict dst, const char *restrict src);char* mycpy(char *dst, const char* src){    char *ret = dst;    while(*dst++ = *src++);    *dst = '\0';    return ret;}char* mycpy(char *dst, const char* src){    int idx = 0;    while(src[idx] != '\0'){        dst[idx] = src[idx];        idx++;    }    dst[idx] = '\0';    return dst;}

复制一个字符串:

char *dst = (char*)malloc(strlen(src) + 1);strcpy(dst, src);
  • strchr:字符串中找字符
    • char *strchr(const char *s, int c);
    • 字符串中找字符串:char *strstr(const char *s1, const char *s2)
    • 忽略大小写:char *strcasestr(const char *s1, const char *s2)
0 0
原创粉丝点击