前言:
此刻姐妹们对“c语言指针读取”大约比较重视,咱们都想要学习一些“c语言指针读取”的相关内容。那么小编也在网络上收集了一些关于“c语言指针读取””的相关知识,希望姐妹们能喜欢,看官们一起来了解一下吧!1.指针的概念
指针变量也是一个变量。
指针存放的内容是一个地址,该地址指向一块内存空间。
指针是一种数据类型。
指针在内存中的大小:
所有的指针地址编号在32位系统下是一个4字节的无符号整数,在64位系统下是8字节的无符号整数。
下面通过代码简单介绍:
#include<stdio.h>int main01(){ int* p;//定义了一个可以执行int类型地址的指针变量,叫p int a;//定义了一个int型的变量,叫a a = 1; p = &a;//将a的内存地址赋值给p printf("%p\n", p); *p = 10;//通过指针变量间接访问a的值,*p代表指针指向变量的值,p代表变量地址 printf("%d\n", a); a = 100; printf("%d\n", *p); int b = 2; p = &b;//p指向b的地址 *p = 20; printf("%d\n", b); char* p1 = &a;//两个类型不同的地址,会导致值出错 a = 123456; *p1 = 0; printf("a=%d\n", a); void* p2;//可以指向任何类型地址,void代表无类型 return 0;}
2.空指针和野指针
空指针就是指向了NULL的指针变量。
野指针,没有指向任何有效地址的指针变量,所以代码中避免出现野指针,如果一个指针不能确定指向任何一个变量的地址,那么就将这个指针变为空指针。
#include<stdio.h>int main0201()//指针在内存中的大小是固定的{ char* p1; int* p2; long long* p3; printf("%lu,%lu,%lu\n", sizeof(p1), sizeof(p2), sizeof(p3)); return 0;}//NULL在C语言中是一个宏常量,值是0.int main0202()//野指针和空指针{ //int* p;//未初始化过值的指针,是野指针 //*p = 100; int* p; p = NULL;//如果一个指针变量没有明确指向一块内存,那就把这个变量指向NULL return 0;}
3.const与指针之间的关系
const修饰谁,谁的值就不能改变
#include<stdio.h>int main0301()//指向常量的指针{ int a = 5; const int* p = &a;//const修饰*p,则*p不可修改 //*p = 10;err printf("%d\n", a); const int b = 11; //b = 0;err 不可修改 int *p1;//通过修改指针指向内存地址中的值,达到修改常量的值 p1 = &b; *p1 = 0; printf("%d\n", b); return 0;}int main0302()//常量指针{ int a = 10; int b = 20; int* const p2 = &a; //p2 = &b;//err 不能修改指针常量指向的内存地址 *p2 = 20;//但可以修改内存地址中的值 printf("%d", a);}
4.指针与数组的关系
#include<stdio.h>int main0401(){ int a[10] = { 1,2,3,4,5,6,7,8,9,10 }; int* p; //p = a; p = &a[2];//此时p[0]指向a[2],p[1]指向a[3] p[3] = 20;//当指针变量指向一个数组时,C语言规定指针变量名可当数组名使用 printf("%lu,%lu\n", sizeof(a), sizeof(p)); for (int i = 0; i < 10; i++) { printf("a[%d]=%d\n", i, a[i]); } return 0;}int main0402(){ int a[10] = { 1,2,3,4,5,6,7,8,9,10 }; int* p = a;//指针指向a首地址 p[3] = 100;//即 *(p+3)=100 for (int i = 0; i < 10; i++) { printf("a[%d]=%d\n", i, a[i]); } return 0;}
5.指针的运算
赋值:int *p=&a;
求值:int i=*p;
取指针地址:int **pp=&p;
将一个整数加(减)给指针:p+3; p-3;
增加(减少)指针值p++,p—
求差值p1-p2通常用于同一个数组内求两个元素之间的距离
比较p1==p2通常用来比较两个指针是否指向同一个位置。
#include<stdio.h>int main0501()//指针运算不能有乘除{ //long a = 0; //long* p = &a;// printf("%p,%p,%p\n", p, p + 1, p + 2); int a[10] = { 0 }; int* p = a; p += 5; *p = 1; p -= 2; *p = 3; // *p= 2;//err for (int i = 0; i < 10; i++) { printf("a[%d]=%d\n", i, a[i]); } return 0;}//指针变量可计算,int* +1,变化4个整数,char* +1,变化一个整数//C语言中所有数据类型都可看做为一个char的数组int main0502()//用char修改一个int类型的地址{ int a = 0x12345678;//int是4个char 故p[0]=0 将a的末尾两位78改为0 char* p = (char*)&a; p[3] = 0; printf("%x\n", a); printf("----------------------\n"); char b[20] = { 0 }; int* p1 = (int*)b; p1[3] = 0x12345678;//位移了char中的12个字节,因为p1是int型 for (int i = 0; i < 20; i++) { printf("b[%d]=%x\n", i, b[i]); } return 0;}
6.利用指针给二维数组排序
#define _CRT_SECURE_NO_WARNINGS#include<stdio.h>int main0701(){ char a[2][5] = { {1,4,3,2,5} ,{9,7,6,8,10} }; char* p = &a; for (int i = 0; i < 10-1; i++) { for (int j = 0; j < 10 - i - 1;j++) { if (p[j] > p[j + 1]) { char temp = p[j]; p[j] = p[j + 1]; p[j + 1] = temp; } } } for (int i = 0; i < 2; i++) { for (int j = 0; j < 5; j++) { printf("a[%d][%d]=%d\n", i, j, a[i][j]); } } return 0;}
7.指针数组
#define _CRT_SECURE_NO_WARNINGS#include<stdio.h>//地址编号在32位系统下是4字节,在64位系统下是8字节int main0801(){ char* a[10]; int* b[10]; printf("%lu,%lu\n", sizeof(a), sizeof(b)); int i = 0; //a = &i;//err a是数组名是常量,不是指针 a[0] = &i;//OK printf("%lu,%lu\n", sizeof(b[0]),sizeof(*b[0])); return 0;}int main0802(){ int* arr[10] = { NULL }; int a, b, c; arr[0] = &a; arr[1] = &b; arr[2] = &c; *arr[0] = 10; printf("%d\n", a); return 0;}
8.二级指针和三级指针
#define _CRT_SECURE_NO_WARNINGS#include<stdio.h>int main0901(){ int a = 0; int* p = &a; int** pp = &p;//二级指针,指向指针的指针 **pp = 10; printf("%d\n", a); return 0;}int main0902(){ int a[10]; int* p = a; p[0] = 0; p[1] = 2; int* b [10]; int** p1 = b; p1[0] = NULL; printf("%lu\n", sizeof(p1[0])); return 0;}
#define _CRT_SECURE_NO_WARNINGS#include<stdio.h>int main010(){ int a = 0; int* p = &a; int** pp = &p; int*** ppp = &pp;//三级指针 ***ppp = 10; printf("%d\n", a); return 0;}
9.指针作为函数参数
函数的参数可以是指针类型。,它的作用是将一个变量的地址传送给另一个函数。
void test(int*p);//定义一个函数,形参是int*类型。
C语言中如果想通过函数内部修改外部实参的值,那么就需要给函数的参数传递这个实参。
#define _CRT_SECURE_NO_WARNINGS#include<stdio.h>void swap(int *a, int *b){ int temp = *a; *a = *b; *b = temp;}//形参的值改变后不会影响实参,故使用指针来改变实参的值int main11(){ int a = 1; int b = 2; swap(&a, &b); printf("a=%d,b=%d\n", a, b); return 0;}
10.数组名作为函数参数
当数组名作为函数参数时,C语言将数组名解释为指针
如果数组名作为函数参数,那么这个就不是数组名了,而是一个指针变量名。
当把一个数组名作为函数参数的时候那么会在函数内部就不知道这个数组的元素个数了,需要再增加一个参数来标明这个数组大小。
#define _CRT_SECURE_NO_WARNINGS#include<stdio.h>//void test(int a[])//void test(int a[10])//void test(int *a)//三种写法一致void test(const int *a)//添加const是为了不让函数内部修改数组成员的值{ printf("%lu\n", sizeof(a)); int* p = (int*)a; p[5] = 100; //a[5] = 50; //err, 有const故不能修改数组成员的值}//当数组名作为函数形参时,其实是这个指针变量名int main() { int a[10] = { 1,2,3,4,5,6,7,8,9,10 }; printf("%lu\n", sizeof(a)); test(a); for (int i = 0; i < 10; i++) { printf("a[%d]=%d\n", i,a[i]); } return 0;}
标签: #c语言指针读取