C指针的基本用法

基本使用

// 创建int型对象
int a = 10;  
// & 是取地址符, * 是代表创建的对象是指针, 将a的内存地址赋值给pt_a指针
int * pt_a = &a;  
// *pt_a 是取指针指向的内容,pt_a是内存地址, 将pt_a指向内容修改为常量 11
*pt_a = 11;
// 输出a 变量内容为 11
std::cout << a;  

①. int *p;
②. *p=10;
两个的区别:前一个起标识作用,表明定义的p是一个指针,后者的表示通过访问p指向的地址空间

指向指针的指针

int a = 10;  
int *p = &a; //指向int型的指针  
int **p1 = &p; //指向指针的指针  
int ***p2 = &p1; //三级指针  

*p2相当于访问p1;
**p2相当于访问p;
***p2相当于访问a;
*p1相当于访问p;

数组指针

int array[] = {-1, 2, -3, 4};  
int len = (sizeof(array) / sizeof(array[0]));  
for (int i = 0; i < len; ++i) {  
    printf("[%d] = %d\n", i, array[i]);
}
// 默认指向数组第一个元素
int *p = array;  // 或者 int *p = &array[0]  
printf("first = %d\n", *p); // 输出-1 数组第1个元素  
printf("next = %d\n", *(p + 1)); // 输出2 数组第2个元素  
// 通过指针遍历数组
for (int i = 0; i < len; ++i) {  
   printf("[%d] = %d\n", i, *(p + i));
}
// 通过指针下标获取 元素
printf("%d", p[2]);  // 输出第3个元素 -3  
return 0;  

1.数组元素的三种访问形式:

  • 数组名[下标] array[0]
  • 指针变量名[下标] p[0]
  • *(p+1) *(p)

2.指针变量的+1究竟是加多少?这取决于指针的类型,如果是char类型则加1个字节,如果是int类型的,则加4个字节。

3.利用指针来接收一个数组,指针变量指向了数组的首元素。 如果传递的指p针是 &array[1], *(p + 1) 就会变成第三个元素值

字符串指针

char str1[] = "123456";  // 适用需要修改子串的情况  
const char * str2 = "7891011"; // 适用内容不需要修改,且经常被使用  
// 修改第一个元素
str1[0] = 'Y';  
printf("str1 =%s\n", str1);  
printf("str2 =%s\n", str2);  
// 第二个元素, char * 是常量不能修改
printf("first =%c\n", *(str2 + 1));  

指针函数

void (*p)(); // void指针变量指向的函数没有返回值,()表示p指向的函数没有形参

void test() {  
    printf("调用了test函数\n");
}

int main() {  
    p = test; // 有指针p,把指针p指向函数
    test(); // 直接调用test()
    (*p)(); // 利用指针变量简介调用  (*p)()
    p(); // 简化使用p()
    return 0;
}

练习: 编写一个函数,计算a和b的和与差(一个函数返回两个值)

int sumAndSub(int a, int b, int *result) {  
    *result = a + b;
    return a - b;
}

int main() {  
    int sum;
    int sub = sumAndSub(5, 6, &sum);
    std::cout << sub << "," << sum << std::endl;
    return 0;
}

有关指针的疑问

注意:任何类型的指针都占据8个字节的存储空间,那么为什么还要为指针加上类型呢? 对下面一段代码进行内存分析,可以证明指针类型不正确带来的严重后果。

int i = 2;  
char c = 1;  
int *p = &c; // 本应该是char类型的,写成了int类型  
printf("c的值是%d\n", *p); // 打印结果为513,而非1  
printf("c的值是%d\n",c); // 值为1  

下面是上述代码的结果的内存分析:

指针p访问的本应该是1个字节空间的数据,此时因为指针的类型是int型的,因此程序自然的从指向的地址0x0a开始读取了4个字节的数据,访问的数据从1变成了513。

提示:明确了指针的数据类型,指针才能够正确的访问应该访问的空间数据。

参考文档