C语言 三个学生 4门课程 指针,C语言学习与总结---第八章:指针[03]

指针[03]

8.6 指针与字符串

8.6.1 字符串的表示

8.6.2 字符数组作函数参数

8.6.3 区别:字符指针变量和字符数组

8.7 指向函数的指针

8.7.1 函数的指针

8.7.2 用函数指针变量调用函数

8.7.3 用指向函数的指针作函数参数

8.8 返回指针值的函数

8.9 指针数组和多重指针

8.9.1 指针数组

8.9.2指向指针数据的指针

8.6 指针与字符串

8.6.1 字符串的表示

(1)用字符数组存放一个字符串

#include

int main()

{

char string[] = "I Love China!";

printf("%s\n", string);

return 0;

}

(2)用字符指针指向一个字符串

#include

int main()

{

char* string = "I Love China!";

printf("%s\n", string);

return 0;

}

注意:

char* string = "I Love China!";

等价于

char* string; string = "I Love China!";

而不是

char* string; *string = "I Love China!";

例,字符串的复制:将字符数组a里面的字符串复制到字符数组b.

#include

int main()

{

char a[] = "I am a boy.", b[20];

int i;

for (i = 0; *(a + i) != '\0'; i++)

*(b + i) = *(a + i);

*(b + i) = '\0'; //当循环结束时,指针位置跳到i+1,正好是结束符的位置;

printf("string a is : %s\n", a);

printf("string b is : ");

for (i = 0; b[i] != '\0'; i++)

printf("%c", b[i]);

printf("\n");

return 0;

}

用指向字符数组的指针实现:

#include

int main()

{

char a[] = "I am a boy.", b[20], * p1, * p2;

p1 = a;

p2 = b;

for (; *p1 != '\0'; p1++, p2++)

*p2 = *p1;

*p2 = '\0';

printf("string a is: %s\n", a);

printf("string b is: %s\n", b);

return 0;

}

8.6.2 字符数组作函数参数

(1)实参形参都为字符数组

#include

void copy_string(char from[], char to[]);

int main()

{

char a[] = "I am a teacher.";

char b[] = "you are a student.";

printf("string a = %s\nstring b = %s\n", a, b);

printf("copy string a to string b: \n");

copy_string(a, b);

printf("\nstring a = %s\nstring b = %s\n", a, b);

return 0;

}

void copy_string(char from[], char to[])

{

int i = 0;

while (from[i] != '\0')

{

to[i] = from[i];

i++;

}

to[i] = '\0';

}

(2)实参为指针变量

#include

void copy_string(char from[], char to[]);

int main()

{

char a[] = "I am a teacher.";

char b[] = "you are a student.";

char* from = a, * to = b;

printf("string a = %s\nstring b = %s\n", a, b);

printf("copy string a to string b: \n");

copy_string(from, to);

printf("\nstring a = %s\nstring b = %s\n", a, b);

return 0;

}

(3)形参为指针变量

void copy_string(char* from, char* to)

{

for (; *from != '\0'; from++, to++)

*to = *from;

*to = '\0';

}

或者

void copy_string(char* from, char* to)

{

while ((*to = *from) != '\0')

{

to++;

from++;

}

}

8.6.3 区别:字符指针变量和字符数组

(1)字符指针变量

char *a=″I love China!″;

等价于

char*a;a=″I love China!″;

而字符数组

char str[14] =″I love China!″;

不能等价于

char str[14];str[] =″I love China!″;

(2)字符数组的输入:

char str[10];scanf(″%s″,str);

但是字符指针变量

char *a;scanf(″%s″,a);

却是错误的,正确输入为:

char *a, str[10];a = str;scanf(″%s″,a);

8.7 指向函数的指针

8.7.1 函数的指针

用指针变量可以指向一个函数;函数在编译时被分配给一个入口地址这个函数的入口地址就称为函数的指针;函数名代表函数的入口地址;

8.7.2 用函数指针变量调用函数

一般定义形式:

数据类型 (*指针变量名)(函数参数表列)

例如这个简单的比较大小的函数

#include

int main()

{

int max(int, int);

int a, b, c;

scanf("%d,%d", &a, &b);

c = max(a, b);

printf("a=%d,b=%d,max=%d\n", a, b, c);

return 0;

}

int max(int x, int y)

{

int z;

if (x > y) z = x;

else z = y;

return z;

}

主函数里面可以使用函数指针变量:

#include

int main()

{

int max(int, int);

int (*p)(int, int);/*类型要跟被指向函数类型一致,

参数表列类型也要跟被指向函数一致,(*p)的括号不能省略*/

int a, b, c;

p = max;

scanf("%d,%d", &a, &b);

c = (*p)(a, b);

printf("a=%d,b=%d,max=%d\n", a, b, c);

return 0;

}

注意:

(1)* p两侧的括号不能省略,表示p先于 * 结合,是指针变量,然后再与后面的()结合,表示此指针变量指向函数。

(2)对指向函数的指针变量,像p+n、p++、p–等运算是没有意义的。

8.7.3 用指向函数的指针作函数参数

指向函数的指针作为参数,可以实现函数地址的传递,这样就能够在被调用的函数中使用实参函数。

a046ab5653874c91cb318034bf4b78f6.png

例,有两个整数a和b,由用户输入1,2或3。输入1时,输出a和b中大者;输入2时,输出a和b中小者;输入3时,输出a和b之和。

#include

int main()

{

void fun(int, int, int (*p)(int, int));

int max(int, int);

int min(int, int);

int add(int, int);

int a = 34, b = -21, n;

scanf("%d",&n);

if (n == 1) fun(a, b, max);

else if (n == 2) fun(a, b, min);

else if (n == 3) fun(a, b, add);

return 0;

}

void fun(int x,int y,int(*p)(int, int))

{

int result;

result = (*p)(x, y);

printf("%d\n", result);

}

int max(int x, int y)

{

int z;

if (x > y) z = x;

else z = y;

return z;

}

int min(int x, int y)

{

int z;

if (x < y) z = x;

else z = y;

return z;

}

int add(int x, int y)

{

int z;

z = x + y;

return z;

}

第4行中,第三个参数是指向函数的指针,发生调用时,根据实参决定形参指针指向哪个函数,例如第11行中,函数调用

fun(a, b, min);

void fun(int, int, int (*p)(int, int))

中的形参(*p)指向函数min;

8.8 返回指针值的函数

一个函数可以带回一个整型值、字符值、实型值等,也可以带回指针型的数据,即地址。

一般定义形式为:

类型名 *函数名(参数表列);

例如:

int *a(int x,int y);

注意:

*a两侧没有括号,在a的两侧分别为*运算符和()运算符。

而()优先级高于*,因此a先与()结合,这是函数形式。

前面有一个*,表示此函数是指针型函数,即函数值是指针。

例,有若干个学生的成绩(每个学生有4门 课程),要求在用户输入学生序号以 后,能输出该学生的全部成绩。

#include

int main()

{

float score[][4] = { {60,70,80,90},{56,89,67,88},{34,78,90,66} };

float* search(float(*p)[4], int n);

float* p1;

int i, k;

printf("enter the number of student: ");

scanf("%d", &k);

printf("The scores of No. %d are: \n", k);

p1 = search(score, k);

for (i = 0; i < 4; i++)

printf("%5.2f\t", *(p1 + i));

printf("\n");

return 0;

}

float* search(float(*p)[4], int n)

{

float* pt;

pt = *(p + n);

return pt;

}

例,对上例中的学生,找出其中有不及格课程的学生及其学生号

#include

int main()

{

float s[][4] = { {60,70,80,90},{56,89,67,88},{34,78,90,66} };

float* search(float(*pr)[4]);

float* p;

int i, j;

for (i = 0; i < 3; i++)

{

p = search(s + i);

if (p == *(s + i))

{

printf("No. %d scores;", i);

for (j = 0; j < 4; j++)

printf("%5.2f, ", *(p + j));

printf("\n");

}

}

return 0;

}

float* search(float(*p)[4])

{

int i;

float* pt;

pt = NULL;

for (i = 0; i < 4; i++)

if (*(*p + i) < 60) pt = *p;

return pt;

}

8.9 指针数组和多重指针

8.9.1 指针数组

一个数组,若其元素均为指针类型数据,称为指针数组,即指针数组中的每一个元素都相当于一个指针变量。

一维指针数组的定义形式为: 类型名*数组名[数组长度];

例如:

int *p[4];

注意:

由于[]比* 优先级高,因此p先与[4]结合,形成p[4]形式,这是数组形式,它有4个元素。然后再与*结合,表示此数组是指针类型的,每个数组元素都是一个指针变量。

例如,下面这个程序

#include

#include

void sort(char* name[], int n);

void print(char* name[], int n);

int main()

{

char* name[] = { "Follow me", "BASIC",

"Great Wall", "FORTRAN", "Computer design" };

int n = 5;

sort(name, n);

print(name, n);

return 0;

}

void sort(char* name[],int n)

{

char* temp;

int i, j, k;

for (i = 0 ; i < n - 1; i++)

{

k = i;

for (j = i + 1; j < n; j++)

if (strcmp(name[k],name[j]) > 0) k = j;

if(k!=i)

{

temp = name[i];

name[i] = name[k];

name[k] = temp;

}

}

}

void print(char* name[],int n)

{

int i;

for (i = 0; i < n; i++)

printf("%s\n", name[i]);

}

afc316784eb94ebe8460e737b78bedf0.png

b3d3b0fde0ea53ef23c2b6ccdc5fa295.png

fbc9d86e9a7e1be6b978f802b6544988.png

运行结果:

2312766d3997d4c7a100bb2fced3f336.png

8.9.2指向指针数据的指针

定义一个指向指针数据的指针变量:

char **p;

p的前面有两个* 号。*运算符的结合性是从右到左,因此**p相当于 * ( * p)。

如果没有最前面的 * ,那就是定义了一个指向字符数据的指针变量。

现在它前面又有一个*号,表示指针变量p是指向一个字符指针变量的。

*p就是p所指向的另一个指针变量。

#include

int main()

{

char* name[] = { "Follow me", "BASIC",

"Great Wall", "FORTRAN", "Computer design" };

char** p;

for(int i=0;i<5;i++)

{

p = name + i;

printf("%s\n", *p);

}

return 0;

}

运行结果

c9bd09662397473e1215194e3be17f45.png

b465e8e2e49526c126ee30117b539546.png

再如

1.#include

2.int main()

3.{

4. int a[5] = { 1, 3, 5, 7, 9 };

5. int* num[5] = { &a[0], &a[1], &a[2], &a[3], &a[4] };

6. int** p,i;

7. p = num;

8. for(i=0;i<5;i++)

9. {

10. printf("%d\n", **p);

11. p++;

12. }

13. return 0;

14.}

运行结果

cf5d72df46334b5de5053954a491bd31.png

82aaf9e9e3dfa9a1b5c093a402f76ef9.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值