目录
一、指针和数组
🍐 数组名指向首地址
🍊 例子
二、数组作为函数参数
🍋 数组名作为函数参数,为什么必须传递数组大小?
三、指针和字符数组
🍌怎么样存储一个string?
🍉数组和指针是以相似方式使用的不同类型
🍇 例子
四、指针与二维数组
🍓 数组在计算机中的组织形式
五、指针与多维数组
🍈 例子
一、指针和数组
🍐 数组名指向首地址
int *p=&A[0]
int *p=A;
🍊 例子
#include<stdio.h>
int main()
{
int A[] ={2,4,5,8,1};
int i;
int *p = A;
p++;
// A++; // invalid!! compile error
printf("Address &A= %lu\n", &A);
printf("Address A= %lu\n", A);
for (int i=0; i < 5; i++) {
printf("Address = %lu\n", &A[i]);
printf("Address = %lu\n", A+i);
printf("Value = %lu\n", A[i]);
printf("Value = %lu\n", *(A+i));
}
return 0;
}
Notes:
数组名不能自增。
输出:
Address &A= 140737488347616
Address A= 140737488347616
Address = 140737488347616
Address = 140737488347616
Value = 2
Value = 2
Address = 140737488347620
Address = 140737488347620
Value = 4
Value = 4
Address = 140737488347624
Address = 140737488347624
Value = 5
Value = 5
Address = 140737488347628
Address = 140737488347628
Value = 8
Value = 8
Address = 140737488347632
Address = 140737488347632
Value = 1
Value = 1
二、数组作为函数参数
当数组作为函数参数时,当传入 数组名[] (A [] ) 并不会将整个数组拷贝一遍,编译器将形参的int A[ ]理解为指针,而非数组。
🍋 数组名作为函数参数,为什么必须传递数组大小?
#include<stdio.h>
// int SumOfElements(int *A)
int SumOfElements(int A[])
{
int i,sum=0;
int size=sizeof(A)/sizeof(A[0]); // 这里是A被理解为一个指针,sizeof(A)=8
printf( "size of A = %d,size of A[0] = %d\n",sizeof(A),sizeof(A[0]) );
for(i=0;i<size;i++)
{
sum += A[i];
}
return sum;
}
int main()
{
int A[] = {1,2,3,4,5};
int total= SumOfElements(A);
printf( "数组元素之和 = %d\n",total );
printf( "size of A = %d,size of A[0] = %d\n",sizeof(A),sizeof(A[0]) );
}
输出
size of A = 8,size of A[0] = 4
数组元素之和 = 3
size of A = 20,size of A[0] = 4
改进
#include<stdio.h>
// int SumOfElements(int *A, int size)
int SumOfElements(int A[], int size)
{
int i,sum=0;
for(i=0;i<size;i++)
{
sum += A[i];
}
return sum;
}
int main()
{
int A[] = {1,2,3,4,5};
int total= SumOfElements(A, sizeof(A)/sizeof(A[0]));
printf( "数组元素之和 = %d\n",total );
}
输出
数组元素之和 = 15
三、指针和字符数组
🍌怎么样存储一个string?
- (size of array) >= (num of characters in string + 1)
- 所有的字符串函数均假定字符串以 \0 结束
#include <stdio.h>
#include <string.h>
int main()
{
char C[10];
C[0] = 'J';
C[1] = 'O';
C[2] = 'H';
C[3] = 'N';
printf("%s\n",C); // 打印出乱码
C[4] = '\0';
printf("%s\n",C); // 正常打印
printf("字符串长度C=%d\n\n",strlen(C)); // \0不算入字符串长度
char s[] = "GZC"; // 自动计算长度,字符串子面值隐含了\0
// char s[4] = "GZC";
// char s[4] = {'G','Z','C','\0'};
printf("%s\n",s);
printf("字符串长度s=%d\n",strlen(s)); // \0不算入字符串长度
printf("size of s=%d\n",sizeof(s)); // 将\0也计算在内
}
输出
JOHN���
JOHN
字符串长度C=4
GZC
字符串长度s=3
size of s=4
🍉数组和指针是以相似方式使用的不同类型
- C2和C1在内存上是不一样的,一个以 \0 结尾,一个只是一个指针
- C2=C1 is valid, C1=C2 is invalid
- C1++也是invalid的
🍇 例子
上图的指针为4 bytes
char test[] = "hello"; //字符串存放在栈空间,可修改
char *test = "hello"; //字符串存放在只读数据区,不可修改
四、指针与二维数组
🍓 数组在计算机中的组织形式
上面这些可以通过画框法来进行理解
换算公式
五、指针与多维数组
🍈 例子
#include<stdio.h>
void func(int A[][2][2])
{
printf("hello world\n");
}
int main()
{
int C[3][2][2] = {{{2, 5}, {7, 9}},
{{3, 4}, {6, 1}},
{{0, 8}, {11, 13}}};
printf("%lu %lu %lu %lu \n",C,*C,C[0],&C[0][0]);
printf("%lu\n",*(C[0][0]+1));
func(C);
return 0;
}
输出
140737488347584 140737488347584 140737488347584 140737488347584
5
hello world