怎么查网站建设是哪家公司深圳龙岗区布吉街道
参考:https://blog.csdn.net/qq_50696399/article/details/141574823
ch8 指针
在对程序进行编译时,系统会给变量分配内存单元。(int分配4个字节,float分配4个字节,char分配1个字节)。内存区中的每一个字节有一个编号,称为地址。
地址指向变量单元,
地址 = 指针
C语言的地址包括位置信息(内存编号,或称纯地址)和它所指向的数据的类型信息,或者说它是带类型的地址。
int i;
编译时,系统为变量i分配了4个字节的内存单元,建立了变量名和地址的对应表。
printf(“%d\n”,i);
通过变量名找到相应的地址,从该4个字节中按照整型数据的存储方式读出i的值。
直接访问:通过变量名找到对应的值;
间接访问:变量名对应的地址放在指针变量,通过地址找到对应的值;
//例8.1
int main()
{int a = 100, b = 10;int * p1 = &a, * p2 = &b;printf("a = %d b = %d", *p1, *p2);return 0;
}//例8.2
int main()
{int a,b;int *p = &a, *q = &b;scanf("%d %d", p, q);if (*p >= *q)printf("%d", *p);elseprintf("%d", *q);return 0;
}//例8.3
int main()
{void swap(int* p, int* q);int a,b;int *p = &a, *q = &b;scanf("%d %d", p, q);if (*p <= *q)swap(p, q);printf("max = %d, min = %d\n", a, b);return 0;
}
void swap(int* p, int* q)//直接改了地址所指向的内容,如果是形参在改,上面的值不会变
{int t = *p;*p = *q;*q = t;
}
//例8.4
void swap(int* p, int* q)//直接改了地址所指向的内容,如果是形参在改,上面的值不会变
{int* t = p;p = q;q = t;
}//例8.5
int main()
{void exchange(int* p, int* q, int* r);void swap(int* p, int* q);int a, b, c;int *p = &a, *q = &b, *r = &c;scanf("%d %d %d", p, q, r);exchange(p, q, r);printf("max = %d, mid = %d, min = %d\n", a, b, c);return 0;
}
void swap(int* p, int* q)//直接改了地址所指向的内容,如果是形参在改,上面的值不会变
{int t = *p;*p = *q;*q = t;
}
void exchange(int* p, int* q, int* r)
{if (*p < *q)//确保*p最大swap(p, q);if (*p < *r)//确保*p最大swap(p, r);if (*q < *r)//确保*q第二最大swap(q, r);
}
指针变量p
p+1不是将p的值简单加1,而是p的值加指针类型所占用的字节数
指针变量p1和p2都指向同一数组的元素时,p2-p1的结果是两个地址差再除以数组元素长度
//例8.6
int main()
{int a[10] = { 0,1,2,3,4,5,6,7,8,9 };for (int i = 0; i < 10; i++)printf("%d ", a[i]);return 0;
}
int main()
{int a[10] = { 0,1,2,3,4,5,6,7,8,9 };for (int i = 0; i < 10; i++)printf("%d ", *(a+i));//a是元素首地址,地址是指针,指针+i不是简单地加ireturn 0;
}
int main()
{int a[10] = { 0,1,2,3,4,5,6,7,8,9 }, *p = a;for (; p < a+10; p++)//p址是指针,指针+i不是简单地加iprintf("%d ", *p);return 0;
}//例8.7
int main()
{int a[10] = { 0,1,2,3,4,5,6,7,8,9 }, *p = a;for (int i = 0; i < 10;i++, p++)//p址是指针,指针+i不是简单地加iprintf("%d ", *p);return 0;
}//例8.8
int main()
{void inv(int* x, int n);int a[10] = {3,7,9,11,0,6,7,5,4,3 }, *p = a;inv(a, 10);for (; p < a + 10; p++)//p址是指针,指针+i不是简单地加iprintf("%d ", *p);return 0;
}
void inv(int* x, int n)
{int* len = x + n / 2;int* y = x + n - 1;//指向尾for (; x < len; x++, y--){int t = *x;*x = *y;*y = t;}
}//例8.10
int main()
{void sort(int* x, int n);int a[10] = {12,34,5,689,-43,56,-21,0,24,65}, *p = a;sort(a, 10);for (; p < a + 10; p++)//p址是指针,指针+i不是简单地加iprintf("%d ", *p);return 0;
}
void sort(int* x, int n)
{for (int i = 0; i < n - 1; i++){int max_val = *(x + i), max_ind = i, t;for (int j = i + 1; j < n; j++)if (*(x + j) > max_val){max_val = *(x + j);max_ind = j;}t = *(x + max_ind);*(x + max_ind) = *(x + i);*(x + i) = t;}
}
通过指针引用多维数组
int a[3][4];
a是二维数组名;a数组包含3个元素a[0],a[1],a[2];
a[0]是一维数组名,a[0]数组包含4个元素a[0][0],a[0][1],a[2][0],a[0][3];
a是二维数组,a[0]是一维数组,a[0]是数组的数组,这是二维数组的角度。
数组名是首元素地址
a含义:a二维数组的元素是每一行,首元素地址是第0行地址,值为&a[0],a指向a[0]
a+1含义:第1行地址,值为&a[1],a+1指向a[1]
a[0]含义:a[0]一维数组的元素是第0行的每一列,首元素地址是第0行 第0列地址,值为&a[0][0],a[0]指向a[0][0]
a[1]含义:第1行第0列地址,值为&a[1][0],a[1]指向a[1][0]
a[0]+1不是简单地加1,a[0]是地址,加的是a[0]类型的字节数;
a[0]+1含义:第0行第1个元素地址,值为&a[0][1],a[0]+1指向a[0][1]
a指向一维数组a[0],a[0]指向列元素a[0][0]。对不同的指针进行加1运算,得到的结果是不同的。
书本原文:从二维数组的角度来看,a代表二维数组首元素的址,现在的首元素不是一个简单的整型元素,而是由4个整型元素组成的一维数组,因此a代表的是首行的起始地址。如果二维数组的首行的起始地址为2000,a+1的值应该是2000+4*4=2016。(一行4个元素,每个元素4个字节)
重要:a[0]和*(a+0)等价;a[i]和*(a+i)等价;
则a[0]+1和*(a+0)+1的值都是&a[0][1];
a[1]+2和*(a+1)+2的值都是&a[1][2]
如果a是二维数组,则a[i]是一维数组名,它只是一个地址,并不是一个存储单元,进而也不是存储单元中的值。
得到地址后在地址前面再加一个解引用得到这个地址所指的值,即(a[0]+1)和*(*(a+0)+1)的值都是a[0][1]
说明:C语言的地址信息包含位置信息和指向数据的类型信息。a[0]是一维数组名,a是二维数组名,二者地址相同,但指向类型不同,一个指向整型数据,一个指向一维数组。用指针变量pt指向这个一维数组,应当这样定义:
int (*pt)[4];
pt指向类型:由4个int元素组成的一维数组;
对比int *p;
p指向类型:一个int元素
简单粗暴的理解:
假设p指向一维数组,那么定义pt时后面多了个[4],说明pt指向二维数组;
星p就是a[0]的值,星(星(pt+i) + j)就是a[i][j]的值
//例8.12
int main()
{int a[3][4] = { 1,3,5,7,9,11,13,15,17,19,21,23 }, *p = a;//p<a+12以a的行元素个数来加,地址的取值上为:a+(12*4*4)//含义分别为:12为要加12次,4为一个int占4字节地址,4为一行4个元素//要循环12*4次,因为p++每次只走一个元素的地址长度,而非一行的地址长度//正常循环12次,地址的取值上为:a+(12*4)for (p = a; p < a[0] + 12; p++){printf("%d ", *p);}return 0;
}//例8.13
int main()
{int a[3][4] = { 1,3,5,7,9,11,13,15,17,19,21,23 }, (*p)[4] = a;//p指向由4个int元素组成的一维数组//*p指向由4个int元素组成的一维数组的第0个int//*(p)+1为0行1列的地址,*(p+2)+1为2行1列的地址//现在是a+3而不是a[0]+12,共有3行,大循环3次,p++每加一次地址加的是一行4个int元素的字节数(4*4)=16for (p = a; p < a + 3; p++){for (int i = 0; i < 4; i++)//小循环4次printf("%d ", *(*(p) + i));printf("\n");}return 0;
}//例8.14
int main()
{void average(float* p, int n);void search(float (*p)[4], int n);float score[3][4] = { 65,67,70,60,80,87,90,81,90,99,100,98 };average(*score, 12);//score是首元素地址,首元素为一行float;*score是首元素地址,首元素为此行的一个floatsearch(score, 2);//score是首元素地址,首元素为一行floatreturn 0;
}
void average(float* p, int n)
{float* p_end = p + n, ave = 0;for (; p < p_end; p++){ave += (*p) / 12;}printf("ave = %f\n", ave);
}
//*p指向一维数组,指向类型为一个float
//(*p)[4]指向二维数组,指向类型为一行float,p是首元素地址,p是数组名
void search(float (*p)[4], int n)
{for (int i = 0; i < 4; i++){printf("%f ", *(*(p+n)+i));}
}//例8.15
int main()
{void search(float (*p)[4], int n);float score[3][4] = {65,67,70,60,58,87,90,81,90,99,100,98};search(score, 3);//(*p)[4]指向类型为4个float组成的数组return 0;
}
void search(float (*p)[4], int n)
{for (int i = 0; i < n; i++){bool flag = true;for (int j = 0;j < 4; j++){if (*(*(p+i)+j) < 60){flag = false;}}if(!flag)for (int j = 0; j < 4; j++)printf("%f ", *(*(p + i) + j));printf("\n");}
}//例8.17
int main()
{//字符串实际为字符数组,有一个虚无的数组名,数组名是首元素地址赋给了stringchar* string = "I love you";printf("%s\n", string);return 0;
}//例8.18
int main()
{char* a = "I love you", b[20];int i = 0;for (; *(a+i) != '\0'; i++)b[i] = a[i];b[i] = '\0';for (int i = 0; *(b + i) != '\0'; i++){printf("%c", b[i]);}return 0;
}//例8.19
int main()
{char* a = "I love you", b[20], *p1 = a, *p2 = b;for (; *p1 != '\0'; p1++, p2++)*p2 = *p1;*p2 = '\0';for (int i = 0; *(b + i) != '\0'; i++){printf("%c", b[i]);} return 0;
}//例8.20
int main()
{void copy_string(char* from, char* to);char* a = "teacher", b[] = "student", *from = a, *to = b;copy_string(from, to);printf("%s\n%s", a,b);return 0;
}
void copy_string(char* from, char* to)
{for (; *from!='\0'; from++,to++){*to = *from;}*to = '\0';
}
指向函数的指针
函数名就是函数的指针,它代表函数的起始地址
定义:
int (*p)(int, int);指针p指向类型为有两个int参数的函数
int (*p)[4];指向类型为4个int组成的数组
int *p;指向类型为一个int元素
使用:(*p)看成函数名完事
//例8.23
int main()
{int find_max(int x, int y);int find_min(int x, int y);int (*p)(int, int) = find_max;//定义指针变量p,它指向find_max的首地址int (*q)(int, int) = find_min;int a, b, choose;scanf("%d %d %d", &a, &b, &choose);if(choose == 1)printf("max = %d", (*p)(a, b));else if(choose == 2)printf("min = %d", (*q)(a, b));return 0;
}
int find_max(int x, int y)
{if (x >= y)return x;elsereturn y;
}
int find_min(int x, int y)
{if (x <= y)return x;elsereturn y;
}//例8.24
int main()
{int fun(int x, int y, int(*p)(int, int));int find_max(int x, int y);int find_min(int x, int y);int add(int x, int y);int a = 34, b = -21, choose;scanf("%d", &choose);if(choose == 1)printf("max = %d", fun(a,b, find_max));else if(choose == 2)printf("min = %d", fun(a, b, find_min));else if (choose == 3)printf("sum = %d", fun(a, b, add));return 0;
}
int fun(int x, int y, int(*p)(int, int))
{return (*p)(x, y);
}
int find_max(int x, int y)
{if (x >= y)return x;elsereturn y;
}
int find_min(int x, int y)
{if (x <= y)return x;elsereturn y;
}
int add(int x, int y)
{return x + y;
}
返回指针值的函数
int *a(int x, int y);
理解:标题的名词是函数,a(int x, int y)是一个函数,返回类型为int星
//例8.25
int main()
{float score[][4] = { 60,70,80,90,56,89,67,88,34,78,90,66 };float* search(float (*p)[4], int n), p;int n;scanf("%d", &n);for (int i = 0; i < 4; i++)printf("%5.2f\t", *(search(score, n)+i));return 0;
}
float* search(float (*p)[4], int n)//返回第n个学生第0门成绩的地址
{return *(p + n);//p是行地址,+n加到了第n行地址,再*解引用得到n行0列地址
}//例8.26
int main()
{float score[][4] = { 60,70,80,90,56,89,67,88,34,78,90,66 };float* search(float (*p)[4]);for (int i = 0; i < 3; i++){if (search(score + i)){ printf("No:%d\n", i);for (int j = 0; j < 4; j++)printf("%f ", *(search(score + i) + j));printf("\n");}}return 0;
}
float* search(float (*p)[4])//p指向类型为1行float
{for (int i = 0; i < 4; i++){if (*(*p + i) < 60)//当前行i列的值return *p;//返回当前行i列的地址}return NULL;
}
指针数组:int* p[4]
理解:p[4]定义一个数组,这个数组类型为int*
对比:int (*p)[4];
理解:用星p定义一个 指针变量p,它指向类型为4个int
//例8.27
int main()
{void sort(char* name[], int n);char* name[] = { "Follow me","BASIC","Great Wall","FORTRAN","Computer design" };sort(name, 5);for (int i = 0; i < 5; i++){printf("%s\n", name[i]);}return 0;
}void sort(char* name[], int n)
{for(int i =0;i<n-1;i++)//每排序一个数要一个大循环for (int j = i + 1; j < n; j++)//排这个数要从剩下的数中找更小的{if (strcmp(name[j], name[i]) < 0){ char* t = name[j];name[j] = name[i];name[i] = t;}}
}//例8.28
int main()
{void sort(char* name[], int n);char* name[] = { "Follow me","BASIC","Great Wall","FORTRAN","Computer design" };char** p;//指针的指针,name已经是存放指针的一个东西了,再多一个*就指向namefor (int i = 0; i < 5; i++){p = name + i;//p指向name,name+i指向name的第i个元素,printf("%s\n", *p);//解引用得到第i个元素的值,就是第i个字符串的地址}return 0;
}//例8.29
int main()
{int a[5] = { 1,3,5,7,9 };char* num[5] = { &a[0],&a[1] ,&a[2] ,&a[3] ,&a[4] };char** p = num;for (int i = 0; i < 5; i++){printf("%d ", **p++);//先**P,再p++}return 0;
}
动态内存分配与指向它的指针变量
全局变量分配在内存的静态存储区;(静态区)
局部变量分配在内存的动态存储区;(栈stack区)
C语言可以动态分配内存,随时弃用;(堆heap区)
void* malloc(unsigned int size);
函数名为malloc,返回类型为指针,指针指向类型为void;
功能:开辟1个长度为size的连续空间
void* calloc(unsigned, unsigned int size);
函数名为calloc,返回类型为指针,指针指向类型为void;
功能:开辟n个长度为size的连续空间
void* realloc(void 星p, unsigned int size);
函数名为realloc,返回类型为指针,指针指向类型为void;
功能:改p指向的内存空间大小为size,成功返回p,不成功返回空指针NULL
void free(void* p)
功能:释放p指向的动态空间
使用:int 星p = (int星)malloc(100);
解释:int *p定义指针变量p,指向类型为int,指向一个动态空间,指针变量的值为动态空间的首地址
malloc函数返回的是void星类型,不能直接引用;强制转换成int星方便引用
//例8.30
int main()
{void check(int* p);int* p = (int*)malloc(5 * sizeof(int));//p[5] = { 67, 98,59,78,57 };//不合法;p[0] = 67; p[1] = 98; p[2] = 59; p[3] = 78; p[4] = 57;check(p);return 0;
}
void check(int *p)
{for (int *p_end = p + 5; p < p_end; p++)if (*p < 60)printf("%d ", *p);
}
一个指针包含3个信息:
1、他是指针类型
2、它的指向类型
3、指针变量的值(地址)
指针是地址,指针变量的值是地址
习题8
//1.2.
int main()
{void sort_num(int* p);void sort_str(char (*p)[4]);int num[3] = { 9,3,6 };char str[][4] = {"abc", "abb", "aaa"};sort_num(num);printf("%d %d %d", num[0], num[1], num[2]);sort_str(str);printf("\n%s\n%s\n%s\n", str[0], str[1], str[2]);return 0;
}
void sort_num(int* p)//p指向num的首元素
{int t;if (*p > *(p + 1))//最小的放第0位{t = *p; *p = *(p + 1); *(p + 1) = t;}if (*p > *(p + 2))//最小的放第0位{ t = *p; *p = *(p + 2); *(p + 2) = t;}if (*(p + 1) > *(p + 2))//次小的放第1位{t = *(p + 1); *(p + 1) = *(p + 2); *(p + 2) = t;}
}
void sort_str(char (*p)[4])//选择法排序
{char t[4];for(int i = 0; i < 2; i++)for(int j = i + 1; j < 3; j++)if (strcmp(*(p + i), *(p + j)) > 0)//*(p + i)=p[i]=i行0列地址=第i行数组的首地址=第i个字符串名{strcpy(t, p[i]);strcpy(p[i], p[j]);strcpy(p[j], t);}
}//3.
int main()
{void input(int* p);void sort(int* p);void output(int* p);int num[10], *p = num;input(p);sort(p);output(p);return 0;
}
void input(int* p)
{printf("输入10个数\n");for (int* p_end = p + 10; p < p_end; p++)scanf("%d", p);
}
void sort(int* p)
{int t;for (int i = 1; i < 10 ;i++){if (*p > *(p + i)){t = *p;*p = *(p + i);*(p + i) = t;}}for (int i = 0; i < 9; i++){if (*(p + 9) < *(p + i)){t = *(p + 9);*(p + 9) = *(p + i);*(p + i) = t;}}
}
void output(int* p)
{printf("输出10个数\n");for (int* p_end = p + 10; p < p_end; p++)printf("%d ", *p);
}//4.
int main()
{void move(int* p, int m, int n);int num[10] = {1,3,5,7,9,0,2,4,6,8}, * p = num;move(p, 3, 10);for (int i = 0; i < 10; i++)printf("%d ", num[i]);return 0;
}
void move(int* p, int m, int n)
{for (int i = 0; i < m; i++)//移动m个数{int t = *(p + n -1);for (int j = n - 2; j >= 0; j--){*(p + j + 1) = *(p + j);}*p = t;}
}//6.
int main() {int str_len(char* str);char str[] = "I love you.", * p = str;printf("字符串长度为%d\n", str_len(str) );return 0;
}
int str_len(char* str)
{return strlen(str);
}//7.
int main() {char* str_copy(char* str, int m);char str[] = "I LOve you.520**", * p = str;printf("%s\n", str_copy(p, 3));return 0;
}char* str_copy(char* str, int m)
{char* str2 = (char*)malloc((strlen(str + m) + 1) * sizeof(char));strcpy(str2, str + m);return str2;
}//8.
int main() {char str[] = "I LOve you.520**", * p = str;int big = 0, small = 0, space = 0, num = 0, other = 0;for (int i = 0; i < strlen(str); i++, p++){if (*p >= 'A' && *p <= 'Z')big++;else if (*p >= 'a' && *p <= 'z')small++;else if (*p >= '0' && *p <= '9')num++;else if (*p == ' ')space++;elseother++;}printf("big = %d, small = %d, num = %d, space = %d, other = %d, ", big, small, num, space, other);return 0;
}//9.
int main() {void trasn(int (*p)[3]);int num[][3] = {1,3,5,7,9,0,2,4,6}, (*p)[3] = num;printf("Orignal:\n");for(int i = 0;i < 3; i++){ for (int j = 0;j < 3;j++){printf("%d\t", num[i][j]);}printf("\n");}trasn(num);printf("trasn:\n");for (int i = 0; i < 3; i++){for (int j = 0; j < 3; j++){printf("%d\t", num[i][j]);}printf("\n");}return 0;
}
void trasn(int (*p)[3])
{for (int i = 0; i < 3; i++){int t;for (int j = i; j < 3; j++){t = p[i][j];p[i][j] = p[j][i];p[j][i] = t;}}
}//11.
int main()
{void sort(char (*p)[3]);char str[10][3] = { "dd","xx", "zz","aa", "tt","yy", "gg","ff", "ww","qq" };sort(str);for (int i = 0; i < 10; i++){printf("%s\n", str[i]);}return 0;
}void sort(char (*p)[3])
{for(int i = 0;i < 9; i++){ char* t = (char*)malloc(3);for (int j = i + 1; j < 10; j++){if (strcmp(*(p + i), *(p + j)) > 0){strcpy(t, *(p + i));strcpy(*(p + i), *(p + j));strcpy(*(p + j), t);}}}
}//12.
int main()
{void sort(char (*p)[10]);char str[10][10] = { "ers","xc", "weqr","joa", "afvds","cxz", "hgeruy","aacas", "ab","babf" };sort(str);for (int i = 0; i < 10; i++){printf("%s\n", str[i]);}return 0;
}void sort(char (*p)[10])
{for(int i = 0;i < 9; i++){ char* t = (char*)malloc(10);for (int j = i + 1; j < 10; j++){if (strcmp(*(p + i), *(p + j)) > 0){strcpy(t, *(p + i));strcpy(*(p + i), *(p + j));strcpy(*(p + j), t);}}}
}//14.
int main()
{void sort(int* p);int num[5] = { 1,2,3,4,5 };sort(num);for (int i = 0; i < 5; i++){printf("%d\n", num[i]);}return 0;
}
void sort(int* p)
{int t;for(int i = 0;i < 5 / 2; i++){ t = p[i];p[i] = p[4 - i];p[4 - i] = t;}
}//15.
int main()
{void f1(int(*p)[5]);void f2(int(*p)[5]);void f3(int(*p)[5]);float a[4][5] = { 90,99,92,94,90,88,86,58,98,40,90,89,87,85,85,67,55,60,51,67 }, i, j, * p = &a[0][0];f1(a);f2(a);f3(a);return 0;
}
void f1(float(*p)[5])
{float ave = 0;for(int i = 0;i < 4; i++){ ave += *(*(p + i)) / 4;}printf("第1门平均分:%f\n", ave);
}
void f2(float(*p)[5])
{for (int i = 0; i < 4; i++){int flag = 0;for (int j = 0; j < 5; j++){if (*(*(p + i) + j) < 60)flag++;}if (flag >= 2){printf("学号:%d\n", i);printf("全部课程成绩:%f %f %f %f %f\n", *(*(p + i) + 0), *(*(p + i) + 1), *(*(p + i) + 2), *(*(p + i) + 3), *(*(p + i) + 4));printf("平均成绩:%f\n", (*(*(p + i) + 0)+ *(*(p + i) + 1)+ *(*(p + i) + 2)+ *(*(p + i) + 3)+ *(*(p + i) + 4) ) / 5);}}
}
void f3(float(*p)[5])
{for (int i = 0; i < 4; i++){float ave = 0;bool flag = true;for (int j = 0; j < 5; j++){ave += *(*(p + i) + j) / 5;}if (ave >= 90){printf("平均成绩90以上学号:%d\n", i);}for (int j = 0; j < 5; j++){if (*(*(p + i) + j) < 85)flag = false;}if (flag){printf("全部成绩85以上学号:%d\n", i);}}
}//16.
int main()
{void f(char* p);float a[4][5] = { 90,99,92,94,90,88,86,58,98,40,90,89,87,85,85,67,55,60,51,67 }, i, j, * p = &a[0][0];char* str = "A123x456 17960? 302tab5876";f(str);return 0;
}
void f(char* p)
{char t[10];int a[5];bool num_flag = 0;for (int i = 0, j = 0, k = 0; p[i] != '\0'; i++)if (p[i] >= '0' && p[i] <= '9'){t[j++] = p[i];if(p[i+1] < '0' || p[i + 1] > '9' || p[i + 1] == '\0'){t[j] = '\0';a[k++] = atoi(t);j = 0;}}for (int i = 0; i < 5; i++)printf("%d\n", a[i]);
}//17.
int main()
{int strcmp_diy(char* p1, char* p2);char str1[] = "BOY";char str2[] = "BOYY";printf("%d\n", strcmp_diy(str1, str2));return 0;
}
int strcmp_diy(char *p1, char *p2)
{int i = 0;for (; p1[i] != '\0' && p2[i] != '\0'; i++){if (p1[i] > p2[i])return 1;if (p1[i] < p2[i])return -1;if (p1[i] == p2[i])continue;}if (p1[i] == '\0' && p2[i] == '\0')return 0;else if (p1[i] == '\0')//前面一样,但是p1短return -1;else if (p2[i] == '\0')//前面一样,但是p2短return 1;
}//18.
int main()
{int n;char month[13][20] = { "", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }, *p[13];for (int i = 0; i < 13; i++){p[i] = month[i];//i行0列地址给指针数组}scanf("%d", &n);printf("%s\n", p[n]);return 0;
}//19.
int main()
{char* new(int n);char* p = new(2);p[0] = 'B'; p[1] = 'B';printf("%c %c %c\n", *p, *(p + 1), *(p + 2));//*(p + 2)为没开辟存储空间时的值free(p);printf("%c %c\n", *p, *(p + 1));//释放后指向这两个地方的值恢复成 没开辟存储空间时的值return 0;
}//20.
int main()
{void sort(char** p);char str[][10] = {"abcd", "aaa", "abbbb", "acde", "aabb"}, * p[5];for (int i = 0; i < 5; i++)p[i] = str[i];char** q = &p;sort(q);for (int i = 0; i < 5; i++){printf("%s\n", *(q+i));}return 0;
}
void sort(char** p)//p是指针的指针,*p是指针,指针是地址,*p是地址,是字符串首元素地址,是字符串名
{for (int i = 0; i < 4; i++){char t[10];for(int j = 0; j < 4 - i; j++)if (strcmp(*(p + j), *(p + j + 1)) > 0)//*(p+j)是第j个字符串名{strcpy(t, *(p + j));strcpy(*(p + j), *(p + j + 1));strcpy(*(p + j + 1), t);}}
}//21.
int main()
{void sort(int** p, int n);int n;printf("input n:\n"); scanf("%d", &n);int* p = (int*)malloc(n * sizeof(int));printf("input n numbers:\n");for (int i = 0; i < n; i++)scanf("%d", &p[i]);int** q = &p;sort(q, n);printf("Sorted:\n");for (int i = 0; i < n; i++){printf("%d ", p[i]);}return 0;
}
void sort(int** p, int n)
{for (int i = 0; i < n - 1; i++){int t;for(int j = 0; j < n - 1 - i; j++)if ((*p)[j] > (*p)[j + 1]){t = (*p)[j];(*p)[j] = (*p)[j + 1];(*p)[j + 1] = t;}}
}