C语言语法入门-指针
9unk Lv5

指针

函数的参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/*程序名:list1001.c*/

#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>

/*---将 n1 和 n2 的和、差分别保存至sum diff---*/
void sum_diff(int n1, int n2, int sum, int diff)
{
sum = n1 + n2;
diff = (n1 > n2) ? n1 - n2 : n2 - n1;
}

int main(void)
{
int na, nb;
int wa = 0, sa = 0;

puts("请输入两个整数。");
printf("整数A:"); scanf("%d", &na);
printf("整数B:"); scanf("%d", &nb);

sum_diff(na, nb, wa, sa);

printf("两数之和为 %d,之差为 %d。\n", wa, sa);

return 0;
}

之前学习过汇编能理解,sum 和 diff 是形参和实参 wa,sa不是一个东西,它们分别在不同的内存地址(指针)上。因此修改sum和diff并不会影响到变量wa和sa

取地址运算符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/*程序名:list1002.c*/
/*
显示对象的地址
*/
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
int n;
double x;
int a[3];

printf("n 的地址:%p\n", &n);
printf("x 的地址:%p\n", &x);
printf("a[0]的地址:%p\n", &a[0]);
printf("a[1]的地址:%p\n", &a[1]);
printf("a[2]的地址:%p\n", &a[2]);

return 0;
}

取地址符号 “&”。

指针

代码清单10-3

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/*程序名:list1003.c*/
/*
通过指针间接地操作身高
*/
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
int sato = 178;
int sanaka = 175;
int masaki = 179;

int* isako, *hiroko;

isako = &sato;
hiroko = &masaki;

printf("一傻子喜欢的人的身高:%d\n", *isako);
printf("羊子换换的人的身高:%d\n", *hiroko);

isako = &sanaka;
*hiroko = 180;

putchar('\n');
printf("佐藤的身高:%d\n", sato);
printf("做中的身高:%d\n", sanaka);
printf("真气的身高:%d\n", masaki);
printf("一傻子喜欢的人的身高:%d\n", *isako);
printf("羊子喜欢的人的身高:%d\n", *hiroko);
return 0;
}

“*” 取指针的值。

指针和函数

指针也可作为函数的参数。

代码清单10-4

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/*程序名:list1004.c*/
/*
通过指针间接修改身高
*/
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>

void hiroko(int* height)
{
if (*height < 180)
*height = 180;
}

int main(void)
{
int sato = 178;
int sanaka = 175;
int masaki = 179;


hiroko(&masaki);

printf("佐藤的身高:%d\n", sato);
printf("做中的身高:%d\n", sanaka);
printf("真气的身高:%d\n", masaki);
return 0;
}

计算和与差

代码清单10-5

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/*程序名:list1005.c*/
/*
计算两个整数的和与差
*/
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>

/*---将n1和n2的和,差分别保存至 *sum和*diff---*/
void sum_diff(int n1, int n2, int* sum, int* diff)
{
*sum = n1 + n2;
*diff = (n1 > n2) ? n1 - n2 : n2 - n1;
}

int main(void)
{
int na, nb;
int wa = 0, sa = 0;

puts("请输入两个整数:");
printf("整数A:"); scanf("%d", &na);
printf("整数B:"); scanf("%d", &nb);

sum_diff(na, nb, &wa, &sa);

printf("两数之和是:%d,之差是%d。\n", wa,sa);
return 0;
}

二值交互

代码清单10-6

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/*程序名:list1006.c*/
/*
将两个数的值互换
*/
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>

void swap(int* px, int* py)
{
int temp = *px;
*px = *py;
*py = temp;
}

int main(void)
{
int na, nb;
int wa = 0, sa = 0;

puts("请输入两个整数。");
printf("整数A:"); scanf("%d", &na);
printf("整数B:"); scanf("%d", &nb);

swap(&na, &nb);

puts("互换了两数的值。");
printf("整数A是%d。\n", na);
printf("整数B是%d。\n", nb);
return 0;
}

将两个值排序

代码清单10-7

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/*程序名:list1007.c*/
/*
将两个整数的值按升序排列
*/
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>

void swap(int* px, int* py)
{
int temp = *px;
*px = *py;
*py = temp;
}

void sort2(int* n1, int* n2)
{
if (*n1 > *n2)
swap(n1, n2);
}

int main(void)
{
int na, nb;

puts("请输入两个整数。");
printf("整数A:"); scanf("%d", &na);
printf("整数B:"); scanf("%d", &nb);

sort2(&na, &nb);

puts("将两个数的值按升序排列。");
printf("整数A是%d。\n", na);
printf("整数B是%d。\n", nb);
return 0;
}

指针的类型

代码清单10-8

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/*程序名:list1008.c*/
/*
将两个实数值进行互换(误例)
*/

#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>

void swap(int* px, int* py)
{
int temp = *px;
*px = *py;
*py = temp;
}


int main(void)
{
double da, db;

puts("请输入两个整数。");
printf("整数A:"); scanf("%lf", &da);
printf("整数B:"); scanf("%lf", &db);

swap(&da, &db);

puts("互换两个数的值。");
printf("整数A是%f。\n", da);
printf("整数B是%f。\n", db);
return 0;
}

指针类型要一样才能正确执行程序。

空指针

1

标量型

2

指针和数组

代码清单10-9

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*程序名:list1009.c*/
/*
显示数组元素的地址(指向元素的指针)
*/

#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void)
{
int i;
int a[5] = { 1,2,3,4,5 };
int* p = a;

for (i = 0; i < 5; i++)
printf("&a[%d]=%p p+%d = %p\n", i, &a[i], i, p + i);
return 0;
}

指针运算符和下标运算符

代码清单10-10

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/*程序名:list1010.c*/
/*
显示数组元素的值和地址
*/

#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void)
{
int i;
int a[5] = { 1,2,3,4,5 };
int* p = a;

for (i = 0; i < 5; i++)
{
printf("a[%d] = %d *(a+%d)=%d p[%d]=%d *(p+%d)=%d\n", i, a[i], i, *(a + i), i,p[i], i, *(p + i));
}
for (i = 0; i < 5; i++)
printf("&a[%d]=%p a+%d = %p &p[%d]=%p p+%d = %p\n", i, &a[i], i, p + i);
return 0;
}

数组和指针的不同点

代码清单10C-1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*程序名:list10C-1.c*/
/*
下标运算符和指针运算符
*/

#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void)
{
int i;
int a[4];
0[a] = a[1] = *(a + 2) = *(3 + a) = 7;
for (i = 0; i < 4; i++)
{
printf("a[%d] = %d\n", i, a[i]);
}
return 0;
}

0[a] 在反汇编中写成 mov ecx,0;mov a[ecx],xxx

数组的传递

数组的传递

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/*程序名:list1011.c*/
/*
数组的传递
*/

#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/*---将数组v开头的n个元素赋给val---*/
void ary_set(int v[], int n, int val)
{
int i;
for (i = 0; i < n; i++)
v[i] = val;
}

int main(void)
{
int i;
int a[] = { 1,2,3,4,5 };
ary_set(a, 5, 99);

for (i = 0; i < 5; i++)
printf("a[%d] = %d\n", i, a[i]);
}

总结

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
/*程序名:summary.c*/
/*
数组的传递
*/

#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define NUMBER 5

/*---交换px和py所指对象的值---*/
void swap(int* px, int* py)
{
int temp = *px;
*px = *py;
*py = temp;
}

/*---冒泡排序法---*/
void bsort(int a[], int n)
{
int i, j;

for (i = 0; i < n - 1; i++)
{
for (j = n - 1; j > i; j--)
{
if (a[j - 1] > a[j])
{
swap(&a[j], &a[j - 1]);
}
}
}
}
int main(void)
{
int i;
int point[NUMBER];

printf("请输入%d人的分数。\n", NUMBER);
for (i = 0; i < NUMBER; i++)
{
printf("%2d号:", i + 1);
scanf("%d", &point[i]);
}

bsort(point, NUMBER);

puts("按升序排列。");

for (i = 0; i < NUMBER; i++)
printf("%2d号:%d\n", i + 1, point[i]);

return 0;

}

练习

练习10-1

3

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/*程序名:lx10-1.c*/

#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>



void adjust_point(int* n)
{
if (*n < 0)
*n = 0;
else if (*n > 100)
*n = 100;
}

int main(void)
{
int n = 200;

adjust_point(&n);

printf("%d\n", n);
return 0;

}

练习10-2

4

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/*程序名:lx10-2.c*/

#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


void decrement_date(int* y,int* m,int* d)
{
*d = *d - 1;
}

void increment_date(int* y, int* m, int* d)
{
*d = *d + 1;
}

int main(void)
{
int y = 2023;
int m = 7;
int d = 27;

//decrement_date(&y, &m, &d);
//printf("昨天是%d年%d月%d日\n", y,m,d);

increment_date(&y, &m, &d);
printf("明天是%d年%d月%d日\n", y, m, d);

return 0;

}

练习10-3

5

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
/*程序名:lx10-3.c*/


#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void sort3(int* n1, int* n2, int* n3)
{
int temp;
if (*n1 > *n2)
{
temp = *n2;
*n2 = *n1;
*n1 = temp;
}
if (*n1 > *n3)
{
temp = *n3;
*n3 = *n1;
*n1 = temp;
}
if (*n2 > *n3)
{
temp = *n3;
*n3 = *n2;
*n2 = temp;
}
}

int main(void)
{
int y = 2023;
int m = 7;
int d = 27;


sort3(&y, &m, &d);
printf("升序排序:\n%d\n%d\n%d\n", y, m, d);

return 0;

}

练习10-4

6

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/*程序名:lx10-4.c*/


#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void set_idx(int* v, int n)
{
for (int i = 0; i < n; i++)
{
*(v+i) = i;
}
}

int main(void)
{
int x[10];


set_idx(x, 10);

for (int i = 0; i < 10; i++)
{
printf("x[%d] = %d\n", i,x[i]);
}

return 0;

}

练习10-5

7

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/*程序名:lx10-5.c*/


#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/*---将数组v开头的n个元素赋给val---*/
void ary_set(int v[], int n, int val)
{
int i;
for (i = 0; i < n; i++)
v[i] = val;
}

int main(void)
{
int i;
int a[] = { 1,2,3,4,5 };
ary_set(&a[2], 5, 99);

for (i = 0; i < 5; i++)
printf("a[%d] = %d\n", i, a[i]);

return 0;

}

数组 a 默认值是指针,而 a[2] 则传递的是 a[2] 的值。&a[2] 指的是数组 a 下标 2 的指针,ary_set 赋值时自然就是从下标 a[2] 的指针处开始赋值。

  • 本文标题:C语言语法入门-指针
  • 本文作者:9unk
  • 创建时间:2023-07-12 15:21:00
  • 本文链接:https://9unkk.github.io/2023/07/12/c-yu-yan-yu-fa-ru-men-zhi-zhen/
  • 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!