字符指针常见错误
#include <stdio.h> int main(int argc, char **argv) { //char *p = "hello"; // hello 在内存中,只用一份,只能读取,不能修改 char p[] = "hello"; // char [] 开辟空间,会把hello字符串常量复制一份,给数组。 printf("%s\n", p); *(p + 0) = 'e'; // 如果是指针,操作是错误,不能修改常量 p[0] = 'e'; // 如果是数组,操作是对的,修改的是,数组里的内容,不是字符串常量 printf("%s\n", p); return 0; }野指针
#include <stdio.h> void swap(int *a,int *b) { int *t; // int t; *t= *a; // t = *a; // *t ,是野指针 *a = *b; *b = *t; } int main(int argc, char **argv) { int a =10; int b =20; swap(&a,&b); /* */ return 0; }函数指针,指针函数
1. 指针函数,函数的返回值是 指针类型 。
char *strcpy(char *dest, const char *src);
strcpy 这个函数的返回值,就是一个指针。 成功,指针指向 dest。
1), 不能返回,是局部作用域的指针。
2) ,希望函数,可以连续调用。 在同一个语句里面。 strcpy(str1,strcpy(str3,str2));
3)希望返回一端内存区域 (数组,堆空间)。
#include <stdio.h> #if 0 int * func1() // 错的 { int a[10]={1,2,3,4,5,6};// 0x2000 这个数组是个局部变量 printf("a addr %p\n",&a[0]); return a;// a == &a[0] ,不要返回局部变量 } int * func2() //对的 { static int a[10]={1,2,3,4,5,6};// 0x2000 printf("a addr %p\n",&a[0]); return a;// a == &a[0] } int main(int argc, char **argv) { int *p =NULL; p = func2(); printf("main p addr %p\n",p); printf("p[0] %d\n",p[0]); return 0; } //............................. int * fun3(int *a,int size) { a[1]=a[3]=a[5]=20; return a; } int main(int argc, char **argv) { int a[10]={0};// 0x2000 int * p = fun3(a,10); printf(" a[1]:%d a[3]:%d\n",a[1],a[3]); printf(" p[1]:%d p[3]:%d\n",p[1],p[3]); return 0; }#include <stdio.h> #include <string.h> int mystrcpy(char *dst, char *src) { while (*src) { *dst = *src; dst++; src++; } *dst='\0'; return 0; } char* mystrcpy2(char *dst, char *src) { char * tmp = dst; while (*src) { *dst = *src; dst++; src++; } *dst='\0'; return tmp; } char* mystrcat(char *dst,char * src) { char* tmp = dst; while(*dst) { dst++; } while(*src) { *dst=*src; src++; dst++; } *dst ='\0'; return tmp; } int main(int argc, char **argv) { char str1[100]="hello"; char str2[100]="ok"; char str3[100]={0}; // char *strcpy(char *dest, const char *src); //strcpy(str1,strcpy(str3,str2));// strcpy(str3,str2);== str3 , strcpy(str1,str3); //printf("str1 is %s\n",str1); // mystrcpy2(str1,mystrcpy2(str3, str2)); // printf("str1 is %s\n",str1); mystrcat(str3,mystrcat(str1,str2)); printf("str3 is %s\n",str3); return 0; }2. 函数指针
前面介绍的指针,基本都是指数据。
函数指针:指向一个函数。本质,指针变量;
函数名,是地址值。里面储存的代码,对数据进行加减乘除操作的。
目的
避免代码的重复。 方便后期代码的扩展。函数功能的解耦合。
回调函数
一个函数被当作参数 ,传递给另外一个函数。 被传递这个参数(函数指针,回调函
数);被动调用。主调函数只是传参(函数)
语法 int add(int a, int b) // int (*) (int,int) { return a + b; } int main(int argc, char **argv) { int (*p)(int, int) =add; // p 函数指针。 add 不能写成add(), 不是对add函数的调用 int a = 10; int b = 20; int ret = 0; ret = add(a, b); printf("add() is %d\n", ret); ret = p(a, b); // 通过函数指针 对函数的调用 printf("p() is %d\n", ret); return 0; }#include <stdio.h> #include <stdlib.h> #include <time.h> int fill_array(int *a, int size) { int i = 0; // for(i=0;i<size;i++) // { // a[i] = rand()%50; // } for (i = 0; i < size; i++) { //(*a)+i = rand()%50; *(a + i) = rand() % 50; } return 0; } int find_num3(int* a,int size) { for(size_t i=0;i<size;i++) { if(0 == a[i]%3) { printf("%d\n",a[i]); } } return 0; } int find_num5(int* a,int size) // int (*) (int*,int) { // int a; int ; int* p ;int* for(size_t i=0;i<size;i++) { if(0 == a[i]%5) { printf("%d\n",a[i]); } } return 0; } //............................................... int div3(int num) // div3 -> int (*) (int) { return 0 == num %3; } int div5(int num) // div3 -> int (*) (int) { return 0 == num %5; } void find_num(int* a,int size, int (*fun) (int) ) { for(size_t i=0;i<size;i++) { if( fun(a[i])) // if( div5(a[i])) { printf("%d\n",a[i]); } } } int main(int argc, char **argv) { srand(time(NULL)); int a[10]={0}; fill_array(a,10); //find_num3(a,10); find_num(a,10,div5); // div5(); return 0; }typedef 关键字
取别名, 给数据类型取别名
1. 普通数据类型 去别名
typedef 老数据类型名 新数据类型名 typedef unsigned char u8; typedef unsigned short u16; typedef char s8; int main(int argc, char **argv) { u8 a; // unsigned char u16 b; // unsigned short s8 c; // char return 0; }2. 简化函数指针的写法
typedef int* (*PFUN)(int ,int ,char* ); // int* func(int a,int b ,char* c) // int* (*)(int ,int ,char* ) // { // return NULL; // } // int func2(int a,int b, int* (*pfun)(int ,int ,char* )) // { // return 0; // } int* func(int a,int b ,char* c) // int* (*)(int ,int ,char* ) { return NULL; } int func2(int a,int b, PFUN pfun) { char str[]={0}; pfun(1,2,str); return 0; }