C语言常用指针

简介: C语言常用指针

C语言中指针是记录数据在内存中的地址(习惯上将这个地址叫做指针),可以直接用来操作和获取数据,本文将带你了解常见的C语言指针。

c语言使用&来获取数据在内存中的地址,使用*来获取指定地址所对应的数据。在接受指针时,需要特定的指针类型来接受指针变量,一般类型中会带有*,也就是说*有两个作用,一个是用来获取特定地址的数据,一个是用来作为指针类型来声明变量。特殊的,对于数组而言,数组名本身就是数组的首地址。

int a = 1;
int* a_point = &a;
int b = *a;  // a == b
char str = 'c';
char* str_point = &str;
char str1 = *str_point;   // str == str1
int list[10] = {1,2,3,4,5,6,7,8,9,0};
// list == &list[0]  数组名就是首元素地址

不同类型的指针类型每次所能在内存操作的数据量有所不同,下图是使用16进制来表示一个4字节的整型数据,对于int*类型指针每一次可以操作4(sizeof(int))个字节的数据,而char*类型的指针每一次可以操作1sizeof(char))个字节的数据。

8e0b3b600cb36cf7be64ea5ee3d606b0_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.png

不同类型指针操作的数据大小

int int_list[10] = {3, 3, 3, 3, 3, 3, 3, 3, 3, 3};
// int_list是int_list的首地址,且类型是int*
for(int i=0;i<10;i++){
    printf("%d ", *(int_list + i));
}
for(int j=0;j<10;j++){
    // 这里先将int_list转换成了char*类型的指针,然后再加一
    printf("%d ", *(((char*)int_list + j)));
}

使用指针可以改变变量在内存中的值,比如像下面这样

int a = 1;
int a_point = &a;
*a = 2;
printf("%d", a); // 2

这种使用指针在全局位置修改一个整型变量的方法是不常用的,更多的是在函数中使用

void add1(int* number){
  *number = *number+1;
}
int a = 1;
add1(&a);
printf("%d",a);  // 2

对于数组而言,数组名本身是一个指针,如果数组中存储的依然是指针的时候,那么这个数组就是指针数组;如果有一个变量指向整个数组的地址,那么这个变量是一个数组指针。总的来说,数组指针是一个指针,它是指向整个数组的指针,指针数组是一个数组,他里面的元素是指针。

「指针数组」

int* list[6] = {1,2,3,4,5,6};

list是一个6个元素的数组,而里面的数据类型是int*

「数组指针」

int list[6] = {1,2,3,4,5,6};
int (*list_point)[6] = &list;

这里的&listlist的值是相同的,但意义是不同的。&list表示的整个数组的地址,而list是表示首元素的地址。他使用起来和一般的首地址相加减也有所不同,下面是两种指针获取元素值的方法。

int list[6] = {1,2,3,4,5,6};
int (*list_point1)[6] = &list;  // 整个数组的地址
int* list_point2 = list;         //首元素地址
for(int i=0; i<6; i++){
  printf("%d ",*(*list_point1 + i));
}
for(int i=0; i<6; i++){
  printf("%d ",*(list_point2 + i));
}

「函数参数设计」

大部分指针会被用在函数中,这是因为在c语言中参数的传递有两种,一种是值传递,一种是地址传递。而对于字符串、数组这样的数据类型,如果传递的是变量名,其本质是属于地址传递的范畴。

int * return_int_list(int* int_list)

对于上面一个函数而言,函数的返回类型是int* ,参数类型是一个int* ,那么在传参的时候可以直接传入一个int型的数组名,函数内部返回的时候也可以返回一个int的数组名,就像下面这样。

int list[10];
int* return_list(int* int_list){
  return int_list
}

在函数中,还有一种参数类型也会用的十分频繁,那就是二级指针。对于一个指针数组而言,在以数组名传参的时候,他的类型就是一个二级指针。具体的可以看下面这个例子

char * names[3] = {
  "Jack",
    "Tom",
    "Tony"
};
void print_names(char** names) {
  for (int i = 0; i < 3; i++) {
    printf("%s\n", names[i]);
  }
}
print_names(names);  // names的类型就是char**

「函数指针」

指向函数的指针就是函数指针。他的形式非常有意思,比如下面的一个函数

int add_two_number(int a, int b){
    return a+b;
}

函数的返回类型是int,函数的参数是两个都是int类型,那么他的函数指针形式就是下面这样

int (*func_point)(int,int) = add_two_number;

总结一下的话,形式就是:

[返回类型] (*函数指针名) [(函数参数的类型)]

以上就是关于c语言中常用的指针知识,除了这些,还有结构体指针、动态内存返回的指针,这些内容不再本文进行讲解,有兴趣了解的同学可以私信告诉我,可以后面再写一篇关于c语言指针的文章。

相关文章
|
2天前
|
C语言
指针进阶(C语言终)
指针进阶(C语言终)
|
2天前
|
C语言
指针进阶(回调函数)(C语言)
指针进阶(回调函数)(C语言)
|
2天前
|
存储 C语言 C++
指针进阶(函数指针)(C语言)
指针进阶(函数指针)(C语言)
|
2天前
|
编译器 C语言
指针进阶(数组指针 )(C语言)
指针进阶(数组指针 )(C语言)
|
4天前
|
存储 C语言
C语言的函数返回值和指针
C|函数返回值(区分各类值)和指针(区分各类存储空间)的细节
|
3天前
|
C语言
【C语言】:详解函数指针变量,函数指针数组及转移表
【C语言】:详解函数指针变量,函数指针数组及转移表
10 2
|
3天前
|
C语言
【C语言】:详解指针数组,数组指针及(二维)数组传参(2)
【C语言】:详解指针数组,数组指针及(二维)数组传参(2)
7 1
|
3天前
|
Serverless C语言
【C语言】:对(一维)数组与指针的深入理解(1)
【C语言】:对(一维)数组与指针的深入理解(1)
8 1
|
6天前
|
C语言
C语言----深入理解指针(5)(一)
C语言----深入理解指针(5)
12 2
|
20小时前
|
C语言
C语言中的函数指针、指针函数与函数回调
C语言中的函数指针、指针函数与函数回调
5 0