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语言指针的文章。

相关文章
|
1月前
|
存储 C语言
【C语言篇】深入理解指针3(附转移表源码)
【C语言篇】深入理解指针3(附转移表源码)
37 1
|
29天前
|
C语言
【c语言】指针就该这么学(1)
本文详细介绍了C语言中的指针概念及其基本操作。首先通过生活中的例子解释了指针的概念,即内存地址。接着,文章逐步讲解了指针变量的定义、取地址操作符`&`、解引用操作符`*`、指针变量的大小以及不同类型的指针变量的意义。此外,还介绍了`const`修饰符在指针中的应用,指针的运算(包括指针加减整数、指针相减和指针的大小比较),以及野指针的概念和如何规避野指针。最后,通过具体的代码示例帮助读者更好地理解和掌握指针的使用方法。
48 0
|
28天前
|
C语言
【c语言】指针就该这么学(3)
本文介绍了C语言中的函数指针、typedef关键字及函数指针数组的概念与应用。首先讲解了函数指针的创建与使用,接着通过typedef简化复杂类型定义,最后探讨了函数指针数组及其在转移表中的应用,通过实例展示了如何利用这些特性实现更简洁高效的代码。
17 2
|
28天前
|
C语言
如何避免 C 语言中的野指针问题?
在C语言中,野指针是指向未知内存地址的指针,可能引发程序崩溃或数据损坏。避免野指针的方法包括:初始化指针为NULL、使用完毕后将指针置为NULL、检查指针是否为空以及合理管理动态分配的内存。
|
28天前
|
C语言
C语言:哪些情况下会出现野指针
C语言中,野指针是指指向未知地址的指针,通常由以下情况产生:1) 指针被声明但未初始化;2) 指针指向的内存已被释放或重新分配;3) 指针指向局部变量,而该变量已超出作用域。使用野指针可能导致程序崩溃或不可预测的行为。
|
1月前
|
存储 C语言
C语言32位或64位平台下指针的大小
在32位平台上,C语言中指针的大小通常为4字节;而在64位平台上,指针的大小通常为8字节。这反映了不同平台对内存地址空间的不同处理方式。
|
1月前
|
存储 算法 C语言
C语言:什么是指针数组,它有什么用
指针数组是C语言中一种特殊的数据结构,每个元素都是一个指针。它用于存储多个内存地址,方便对多个变量或数组进行操作,常用于字符串处理、动态内存分配等场景。
|
1月前
|
存储 C语言
C语言指针与指针变量的区别指针
指针是C语言中的重要概念,用于存储内存地址。指针变量是一种特殊的变量,用于存放其他变量的内存地址,通过指针可以间接访问和修改该变量的值。指针与指针变量的主要区别在于:指针是一个泛指的概念,而指针变量是具体的实现形式。
|
1月前
|
C语言
C语言指针(3)
C语言指针(3)
14 1
|
1月前
|
C语言
C语言指针(2)
C语言指针(2)
15 1