C程序设计(第5版)——谭浩强(2)
- 互联网
- 2025-08-26 05:33:02

参考: 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); else printf("%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不是简单地加i return 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不是简单地加i printf("%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不是简单地加i printf("%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不是简单地加i printf("%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不是简单地加i printf("%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)=16 for (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是首元素地址,首元素为此行的一个float search(score, 2);//score是首元素地址,首元素为一行float return 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() { //字符串实际为字符数组,有一个虚无的数组名,数组名是首元素地址赋给了string char* 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; else return y; } int find_min(int x, int y) { if (x <= y) return x; else return 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; else return y; } int find_min(int x, int y) { if (x <= y) return x; else return 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已经是存放指针的一个东西了,再多一个*就指向name for (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++; else other++; } 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; } } }C程序设计(第5版)——谭浩强(2)由讯客互联互联网栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“C程序设计(第5版)——谭浩强(2)”
上一篇
alphafold3本地部署