7-指针与函数与数组
原创...大约 4 分钟
指针和数组
指针在数组中特别有用。
声明一个数组后就为其元素保留了一个连续的内存地址块。通过指针,可以指向数组第一个元素,然后使用地址运算来遍历数组。
+
向前移动到一个内存位置-
向后移动到一个内存位置
请看下面的程序:
#include <stdio.h>
int main() {
int a[] = {22, 33, 44, 55, 66};
int *ptr = NULL;
ptr = a;
for (int i = 0; i < 5; i++) {
printf("%d ", *(ptr + i));
}
printf("\n");
return 0;
}
:::tips 程序输出值为: 22 33 44 55 66 :::
数组的一个重要概念是:数组的一个重要的概念是:数组名作为一个指针已经指向了数组的第一个元素。 因此,
语句int *ptr = a
等价于int *ptr = &a[0]
语句printf("&d", *a)
将打印数组的第一个元素
下面代码运行输出是?
int a[5] = {22, 33, 44, 55, 66};
int *ptr = a;
int res = *(ptr + 2);
printf("%d", res);
44
更多地址运算
地址运算也认为是指针运算,因为其操作涉及到指针。 除了使用 + 和 - 来指向下一个和上一个内存位置,你还可以使用赋值运算符来改变指针包含的地址。
例如:
#include <stdio.h>
int main() {
int a[5] = {22, 33, 44, 55, 66};
int *ptr = NULL;
ptr = a; /* point to the first array element */
printf("%d %x\n", *ptr, ptr); /* 22 */
ptr++;
printf("%d %x\n", *ptr, ptr); /* 33 */
ptr += 3;
printf("%d %x\n", *ptr, ptr); /* 66 */
ptr--;
printf("%d %x\n", *ptr, ptr); /* 55 */
ptr -= 2;
printf("%d %x\n", *ptr, ptr); /* 33 */
}
:::tips 22 +地址 33 +地址(接邻上边) 66 +地址 55 +地址 33 +地址 :::
⚠️注意 你也可以使用
==
、<
和>
运算符来比较指针地址
填空,使用自增运算符增加指针 ptr 并输出存储的值:
int arr[] = {1, 2, 3};
int* ptr = arr;
ptr __;
printf("%d", ___);
++ *ptr
指针及函数
指针大大扩展了函数的特性。我们不再局限于返回一个值。使用指针参数,函数可以更改实际数据,而不是数据副本。 为了改变变量的实际值,调用语句将地址传递给函数中的指针参数。
例如,以下程序交换两个值:
#include <stdio.h>
void swap(int *num1, int *num2);
int main() {
int x = 25;
int y = 100;
printf("x is %d, y is %d\n", x, y);
swap(&x, &y);
printf("x is %d, y is %d\n", x, y);
return 0;
}
void swap(int *num1, int *num2){
int temp;
temp = *num1;
*num1 = *num2;
*num2 = temp;
}
具有数组参数的函数
数值不能通过值传递给函数。但是,数组名是一个指针,因此仅将数组名传递给函数就是将指针传递给函数。 请看下面程序:
#include <stdio.h>
int add_up(int *a, int num_elements);
int main() {
int orders[5] = {100, 220, 37, 16, 98}; //此处数组不能不固定长度
printf("Total orers is %d\n", add_up(orders,5));
return 0;
}
int add_up(int *a, int num_elements){
int total = 0;
for(int k = 0; k < num_elements; k++){
total += a[k];
}
return (total);
}
471
取最大值:
#include <stdio.h>
int max (int *a, int num_elements);
int main() {
int orders[] = {100, 220, 37, 16, 98, 366};
printf("The max is %d\n", max(orders,6));
return 0;
}
int max (int *a, int num_elements){
int max = a[0];
for(int i = 1; i < num_elements; i++) {
if (max < *(a+i)){
max = a[i];
}
}
return max;
}
声明函数 foo(),该函数使用指针数组参数并返回 int 整数:
___ foo(int ___ arr);
int *
练习:学习struct
结构体后,可以用指针或数字分别和函数组合,表达链表机构
返回数组参数的函数
就像一个数组的指针可以传入一个函数一样,一个数组的指针也可以被返回,如下面的程序:
#include <stdio.h>
int *get_evens();
int main() {
int *a;
int k;
a = get_evens();
printf("%d", *a);
for (k=1; k < 5; k++){
printf(" %d", a[k]);
}
printf("\n");
return 0;
}
int *get_evens(){
static int nums[5];
int k;
int even = 0;
for (k=0; k < 5; k++) {
even +=2;
nums[k] = even;
}
return (nums);
}
:::tips 请注意,声明了一个指针(而不是数组)来存储该函数返回的值。还要注意,当从函数传递局部变量时,需要在函数中将其声明为静态变量。 请记住,a[k]
与 *(a + k)
相同。填空,声明一个返回 int 数组的函数: :::
int ___getArray();
Powered by Waline v3.1.3