寻址,先要寻找地址,然后用其中的数据,怎么找到地址,指针

概述

  • 内存类型的资源的地址,门牌号的代名词

  • *p表示p变量的地址

32位系统,指针大小4字节

存放的地址所指向内存的读取方法是按照所指变量大小以及系统读取

内存属性

  1. 内存操作的大小
  2. 内存的变化属性,可读可写

指针变量

存放指针的盒子 指针指向内存空间要保证合法性

修饰符

限制指针

const

char *p;
//指针可变,但指向的内容不能变
const char; //常用
char const *p;
//指向内容可变,指针不能变,常用在一些硬件资源的指向上
char * const p; //常用
char *p const;

//都不可变
const char * const p; //ROM
#include<stdio.h>

int main(){
        char *p = "Hello World!";
        char a[] = "Hello World!\n";
        char *p1 = a;
        printf("one is %x\n",*p);
        printf("one is %s\n",p);
        *p1 = 'a';
        printf("one is %s\n",p1);
}
//one is 48
//one is Hello World!
//one is aello World!

volatile

防止优化指向内存地址,例如一些硬件资源,在程序中不变,但被外部变,如果优化后可能会出问题

typedef

别名,方便编程


int (*p[10])(int,void(*p)(int))

char *name_t; //name_t是一个指针,指向一个char类型内存
typedef char *name_t //name_t是一个指针类型名称,指向一个char类型的内存

name_t abc; //使用后程序员不需要关心类型,直接用就行

运算符

+ -

指针加减,加减一个单位!(单位大小是sizeof(p))

int a = 100;
a+1 //101

int *p = xxx  [0x12]
p+1  // [0x12 + 1*(sizeof(*p))]

++ –

更新地址

p++;
p--;

[]

变量名[n] //n标签 p[n] 地址内容的标签访问方式 非线性访问, 取出标签里的值

#include<stdio.h>
int main(){
	int a = 0x12345678;
	int b = 0x99991199;
	int *p1 = &b;
	char *p2 = (char *)&b;
	printf("%x,%x,%x\n",*(p1+1),p1[1],*p1+1);
	printf("%x",p2[1]);
	
}
12345678,12345678,9999119a
11

逻辑操作符

>= <= == != 如判断某个指针是否为某个特殊值

int *p1;
int *p2;

p1>p2; //数

*p1 > *p2; // 地址

== !=

跟特殊值比较

if(p == 0x00)
//用NULL避免类型问题

指针必须同类型比较

不同类型编译器过不去

多级指针

int **p; 指针本质–存放地址的盒子 多级就是指针的地址,就是套娃

  • 存放地址的地址空间

描述线性关系

** p[0] Hello p[1] !!! p[n] … p[m] == NULL –>结束标志

#include<stdio.h>
int main(int argc, char **argv){
	int i;
	for(i=0;i<argc;i++){
		printf("argv[%d] is %s  \n",i,argv[i]);
	}
	return 0;
}

./build 123 456 abc

argv[0] is 123
argv[1] is 456
argv[2] is abc
#include<stdio.h>
int main(int argc, char **argv){
	int i = 0;
	while(argv[i] != NULL){
		printf("argv[%d] is %s  \n",i,argv[i]);
		i++;
	}
	return 0;
}