指针

1...
  • 交换a b的值
  • a = a ^ b;
  • b = b ^ a;
  • a = a ^ b;
2...理解-----指针可以通过函数改变函数外的值 

指针所占字节数 只与操作系统有关, 8位或者4位
地址的表示方式为16进制
打印地址用%p
指针变量存储的只是整型变量的首地址(第一个字节的地址)
* 取值运算符, 根据指针变量里存储的地址, 找到并取出对应内存空间的值
&取址运算符, 取到到变量的地址z
指针变量的类型,要与你所要取址的变量的类型相同
指针++, 意味着指针向高地址一次移动其对应的数据类型所占的字节数
指针- -, 意味着指针向低地址依次移动其对应的数据类型所占的字节数

int array[4] = {1, 3, 4, 3}
array 恒等于&array[1]

    int array[ 4 ] = { 1 , 3 , 4 , 3 };
   
int *p = array;
   
printf ( "%d" ,*(p + 1 )); // 结果是 3, 实际上就是打印 array[1];
    printf("%d", *(p + 2));// 结果是 4, 实际上就是打印 array[2];
通过指针,用一个for循环打印出所有的数字
for ( int i = 0 ; i < 4 ; i++) {
       
printf ( "%d " , *(p + i));
    }

   
// 数组在用指针读取数据的时候 , 如果指针类型与数组元素类型不匹配 , 指针会根据自身数据类型选择一次性读取几个字节 , 导致读取数据错误
   
short a[ 4 ] = { 2 , 2 , 0 , 3 };
    int *p = a;
    printf("%d", *p); // 输出 131074

    // 用指针随机产生一个有五个元素的数组 , 并排序 u
   
int arr[ 5 ] = { 0 };
   
int *p = arr;
   
for ( int i = 0 ; i < 5 ; i++) {
        *(p + i) =
arc4random ()% 11 + 10 ;
       
printf ( "%d " , *(p + i));
    }
   
for ( int i = 0 ; i < 5 - 1 ; i++) {
       
for ( int j = 0 ; j < 5 - 1 - i; j++) {
//          if (*(p + j) > *(p + j + 1)) {
           
if (p[j] > p[j + 1 ]) { // 如果指针指向一个数组 , 那么指针名就可以当做数组名来使用 .
               
int temp = *(p + j);
                *(p + j) = *(p + j +
1 );
                *(p + j +
1 ) = temp;
            }
        }
    }
   
printf ( "\n" );
   
for ( int i = 0 ; i < 5 ; i++) {
       
printf ( "%d " ,*(p + i));
    }

char a[] = "abcdefg" ;
   
char *p = a;

   
// 输出 c 以及后面的数
   
printf ( "\n%s " , (p + 2 ));
   
// 输出 c
    printf("\n%c", p[2]);

    char *string[ 3 ] = { "iOS" , "Android" , "Win8" };
//string[3] 里面存储的是字符串 "iOS", "Android", "Win8" 的首地址 .
//    printf("%s",*string);
//    *string[0];
   
//    *string 获取数组中首个元素的值
//    *string[0] 通过 string 数组中收个元素的值找到常量区对应的字符串
//    string[0] 代表数组中首个元素的值
   
    *string = "ISO";// 这里是指针重指向 , 这里的 "ISO" "iOS", "Android", "Win8" 都处在常量区 , 地址不相同 这里把 "ISO" 的地址赋值给了 string
    *string[ 0 ] = "ISO" ; // 错误 !!! 这里 *string[0] 的值处于常量区 , 无法改变


间接访问内存: 通过内存单元编号(地址) 以及数据所占字节数访问内存中的数据

    int a = 20 ;
   
int *p = &a; //& 取地址符 此时 * int 是一个整体 , 告诉编译器 p 是一个存放地址的变量
   
printf ( "%p\n" , p);
   
printf ( "%d\n" , *p); // 使用 p 间接访问 , 如果用 a 则可以直接访问
   
// 对地址的内容直接进行操作
    *p =
40 ;
    printf("%d\n", a);

    // 给指针变量赋值 , 意味着指针重指向
   
int a = 5 , b = 8 ;
   
int *p = &a;
   
printf ( "%d\n" ,*p);
   
   
// 指针类型决定了指针读连续几个字节   指针占用多少字节取决于操作系统的位数 .32 位系统 4 字节 ,64 位系统 8 字节 .
    return 0;


  // 通过指针变量改变变量的值 .
   
int a = 30 ;
   
char b = 20 ;
   
float c = 20 ;
   
int *q = &a;
   
char *w = &b;
   
float *e = &c;
    *q =
40 ;
    *w =
50 ;
    *e =
60 ;
   
    printf("a = %d, b = %c, c = %.2f", a, b, c);

指针作为函数参数,可以改变函数外部改变函数外部变量的值
注意 如果出现*的地方,前面有类型修饰符, 此时*仅仅起到标识作用, 告诉编译器, 我是一个指针
如果出现* 的地方, 前面没有类型修饰符, 此时* 代表取值操作符, 它会把指针指向的区域中的内容取出来或者赋值.
比如: int *a = &b; 这里应该把int * 看做一个整体,指针变量b则是一个内存地址

结构体指针
可以用 (*p).sex 这种形式来访问结构体里面的内容
p -> sex这种方式也可以. 推荐使用后一种方式;

数组名代表数组的首地址 即: 数组首元素地址

上图和下图的输出结果是相同的.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值