1.内存

物理意义上的内存:内存条

C语言中的内存是操作系统抽象出来的

计算机最小数据存储单元:字节  1字节==8bit

  • 计算机会按照字节对内存进行编码,这个编码就是地址
  • 计算机中的地址是一串十六进制数,0x开头
  • CPU会根据约束类型对地址取值

特殊地址:(以32位为例)0x00000000(NULL),没有访问权限

2.地址与指针

指针指向的就是地址

2.1 指针变量的定义格式

数据类型 * 变量名称 = 初始化地址

初始化地址一般指向NULL;但不代表就要使用

2.2 相关操作

2.2.1 取地址

用%p控制输出

2.2.2 取值

用*取值

#include <stdio.h>

int main(int argc, const char *argv[])
{
    int num =10;
    int *p =&num;

    printf("num的地址为%p\n",&num);
    printf("p指向的地址为:%p\n",p);

    printf("p指向地址的数据为:%d\n",*p);
    printf("num对应的数值为:%d\n",*&num);
    return 0;
}

习题:

用指针交换两个数的值

#include <stdio.h>

void Swap(int *num1, int *num2);

int main(int argc, const char *argv[])
{
    int num1 = 5;
    int num2 = 4;
    Swap(&num1, &num2);
}

void Swap(int *num1, int *num2)
{
    int temp = *num1;
    *num1 = *num2;
    *num2 = temp;

    printf("交换后: num1=%d,num2=%d\n", *num1, *num2);
}

3.数组与指针

3.1数组名

保存的是数组首元素的首地址

#include<stdio.h>

int main(int argc, const char *argv[])
{
    int arr[5]={1,2,3,4,5};
    printf("arr存储的地址为:%p\n",arr);
    printf("arr[0]的首地址为:%p\n",&arr[0]);
    printf("arr[1]的地址为:%p\n",&arr[1]);
    printf("arr:%d\n",*arr);

}

3.2 数组中地址的加减

3.2.1 加

数组中地址arr+n对应的地址,实际上是arr+n*sizeof(arr[0])

即  地址   加上   对应数据类型所占字节的长度   得到   的地址

int arr[]={1,2,3,4,5,6,7,8,9,0}

arr[5]+3 得到arr[8]的地址

3.2.2 减

arr[5]-arr[3]

结果是     arr[5] 对应元素 的 首地址   与   arr[3]  对应元素 的 首地址   之间相差多少个对应数据类型的长度

int arr[]={1,2,3,4,5,6,7,8,9,0}

arr[5]-arr[3]       

=4

3.3数组作为函数参数

3.4 字符串与字符数组

3.4.1 遍历字符串

#include<stdio.h>

int main(int argc, const char *argv[])
{
    char ch[]="hello";
    char *p =ch;
    while (*p !='\0')
    {
        printf("%c",*p);
        p++;
    }
    printf("\n");   
}

3.4.2相关函数

  • 拼接
#include<stdio.h>

/**
 * 函数功能:实现字符串的拼接,将str2拼接到str1
 * 
 * @param str1 char类型,拼接的目标字符串
 * @param str2 char类型,拼接的源字符串
 * 
 * @return 无
 */

 
void Joint(char *str1,char *str2);

int main(int argc, const char *argv[])
{
    char str1[128]="hello";
    char str2[]="world";
    printf("拼接前的str1为:%s\n", str1); 
    Joint(str1,str2);
    printf("拼接后的str1为:%s\n", str1);
}

void Joint(char *str1,char *str2)
{
    while (*str1!='\0')
    {
        str1++;
    }
    while (*str2!='\0')
    {
        *str1=*str2;
        str1++;
        str2++;
    }
    *str1 ='\0';
       
}
  • 比较相等
#include <stdio.h>

/**
 * 函数功能:比较两个字符串是否相等
 *
 * @param str1 char类型,比较的第一个字符串
 * @param str2 char类型,比较的第二个字符串
 *
 * @return 无
 */
void Compare(char *str1, char *str2);

int main(int argc, const char *argv[])
{
    char str1[128] = "hello";
    char str2[] = "worldworld";
    Compare(str1, str2);
}

void Compare(char *str1, char *str2)
{
    int i = 0;
    while (str1[i] != '\0' && str2[i] != '\0')
    {
        if (str1[i] != str2[i])
        {
            printf("不相等\n");
        }
        i++;
    }
    if (str1[i] == '\0' && str2[i] == '\0')
    {
        printf("相等\n");
    }
    else
    {
        printf("不相等\n");
    }
}

4.注意

在实际代码中,str 和 *str 的区别核心在于是否进行解引用操作,具体差异如下:

  • 含义不同

str:表示指针变量本身,存储的是内存地址(指向字符串的首地址)。
例如:char *str = "hello"; 中,str 存放的是字符 'h' 的内存地址。

*str:表示对指针进行解引用操作,获取的是指针当前指向的具体字符。
例如:上述例子中,*str 等价于字符 'h'(str 指向的第一个字符)。

  • 用法场景不同

str 用于操作指针本身

移动指针:str++(让指针指向后一个字符)
比较指针地址:if (str == NULL)(判断指针是否为空)
传递指针:func(str)(将指针作为参数传入函数)


*str 用于操作指针指向的内容

获取字符:char c = *str;(获取当前指向的字符)
修改字符:*str = 'A';(修改当前指向的字符值)
判断字符串结束:while (*str != '\0')(当指向的字符不是结束符时循环)

  • 类型不同

str 的类型是指针类型(如 char *)。
*str 的类型是指针指向的数据类型(如 char)。

举例说明

char *str = "hello";
// str 是指针,存储 'h' 的地址
// *str 是 'h',*(str+1) 是 'e',以此类推

printf("指针地址: %p\n", str);   // 输出 str 存储的地址(如 0x7f8a1b2c3d4e)
printf("指向的字符: %c\n", *str); // 输出 'h'

总结:

*str在声明时只作为定义一个指针

在使用时,*str 表示取值,str表示地址。

Logo

纵情码海钱塘涌,杭州开发者创新动! 属于杭州的开发者社区!致力于为杭州地区的开发者提供学习、合作和成长的机会;同时也为企业交流招聘提供舞台!

更多推荐