程序设计复习(二)

程序设计复习

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>
#include <string.h>
int main(){
int a,b;
void exchange(int *p,int *q);
scanf("%d %d",&a,&b);
int *m,*n;
m=&a;
n=&b;
exchange(m,n);
printf("a是%d,b是%d",a,b);
}

void exchange(int *p,int *q){
int *p0;
*p0=*p;
*p=*q;
*q=*p0;
}

这段代码看似没问题,实际上有一个严重的错误。函数中定义的p0开始是并没有明确的指向,是一个野指针,但第二行直接进行了解引用操作,会导致编译直接报错。

正确的写法应该是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>
#include <string.h>
int main(){
int a,b;
void exchange(int *p,int *q);
scanf("%d %d",&a,&b);
int *m,*n;
m=&a;
n=&b;
exchange(m,n);
printf("a是%d,b是%d",a,b);
}

void exchange(int *p,int *q){
int *p0;
p0=*p;
*p=*q;
*q=p0;
}

对于一个一维数组a[5],由于用来存放数组的区域是一块在栈中静态分配的内存,且是连续的,而数组名是这块内存的代表,它被定义为这块内存的首地址,故

  • 它的数组名a是数组首元素的地址。它是一个符号地址常量,不能用作指针。即a==&a[0]
1
2
3
4
5
6
7
8
9
#include <stdio.h>

int main(){
int a[12]={1,2,3,4,5,6,7,8,9,10,11,12};
int p;
p=(a==&a[0]);
printf("%d\n",p);
return 0;
}

结果:

1
1
  • 由于存储数组的内存空间是连续的,因此a+ia[i]的地址。
  • 由上一条,*(a+i)==a[i]a+i==&a[i]的结果都应该是True。因此可以通过指针访问数组元素

一个二维数组的本质是又若干个一维数组作为元素构成的数组。考虑一个二维数组a[2][3]。这个数组有2个元素,每个元素是一个含有3个元素的一维数组。

int a[2][3]={{1,3,2},{4,5,6}}

  • a[0]是这个二维数组当中的第一个元素,即{1,3,2}

  • 考虑a[1][2]时,由上条,把a[1]看做一个整体,它表示的是a中第二个元素这个数列,即{4,5,6}。那么a[1][2]就是a[1]的第三个元素,是6

  • a是一个地址常量,它的值是a中第一个元素所在的内存地址,即a[0]的内存地址。又因为a[0]作为一个数组,它的内存地址就是a[0][0]的地址。

  • a[0]a中第一个元素这个数列的数组名,它是a[0]的首元素的地址常量。因此在数值上,aa[0]相同。

1
2
3
4
5
6
7
8
9
#include <stdio.h>

int main(){
int a[2][3]={{1,3,2},{4,5,6}};
int p;
p=(a==a[0]);
printf("%d\n",p);
return 0;
}

这里会输出1,但会发生警告:

1
2
3
4
new.c:6:9: warning: comparison of distinct pointer types ('int (*)[3]' and 'int *') [-Wcompare-distinct-pointer-types]
p=(a==a[0]);
~^ ~~~~
1 warning generated.

这是因为在C中,此处的a类型是int (*)[3],即指向含有三个元素数组的指针,而a[0]是普通的整型指针,直接比较因为类型并不完全相同会报错。但他们的值事实上的确是相同的。

  • *a表示对a进行解引用,即得到a中的首元素a[0]。然而a[0]作为数组名直接使用,它的本质仍然是a[0]数组的首地址。因此
1
2
3
4
5
6
7
#include <stdio.h>

int main(){
int a[2][3]={{1,3,2},{4,5,6}};
printf("%p,%p\n",a,*a);
return 0;
}

会得到

1
0x7ff7b63e62f0,0x7ff7b63e62f0

程序设计复习(二)
https://brockshuai.github.io/2023/05/31/程序设计复习-1/
作者
神仙魚
发布于
2023年5月31日
许可协议