C语言中char指针赋值及变量声明

15 次阅读

char 是 C 语言中用于表示字符数据的基础类型,而 char * 则是字符指针,常用于字符串处理、字符数组访问以及动态内存操作。实际编程中,char 变量声明、字符指针声明以及指针赋值经常同时出现,但三者的含义并不相同。理解它们之间的关系,是掌握 C 语言指针和字符串操作的重要基础。

一、char变量的基本声明

最简单的 char 变量声明方式如下:

C
char ch;

这里声明了一个名为 ch 的字符变量,可以保存一个字符。

赋值时通常使用单引号:

C
char ch = 'A';

也可以在声明之后再进行赋值:

C
char ch;
ch = 'B';

需要注意,字符常量使用单引号,例如:

C
'A'
'B'
'0'
'
'

而字符串使用双引号:

C
"ABC"
"Hello"

二者在 C 语言中的类型和存储方式不同。

例如:

C
char ch = 'A';
char str[] = "A";

ch 保存的是单个字符,而 str 实际上是一个字符数组,内容包含字符 'A' 以及字符串结束符 ''。

二、char指针变量如何声明

字符指针的声明形式非常简单:

C
char *p;

这里的 p 是一个指针变量,其类型为 char *,表示它可以保存一个 char 对象的地址。

例如:

C
char ch = 'A';
char *p = &ch;

此时内存关系可以理解为:

p
│
▼
ch
'A'

p 保存的是 ch 的地址,而不是字符 'A' 本身。

通过解引用运算符 * 可以访问 p 指向的字符:

C
printf("%c
", *p);

输出:

A

还可以通过指针修改变量:

C
*p = 'B';
printf("%c
", ch);

此时输出:

B

原因是 p 指向的就是 ch。

三、char指针赋值的常见方式

字符指针赋值主要取决于指针指向的数据来源。常见情况包括指向普通 char 变量、指向字符数组以及指向字符串字面量。

1. 指向char变量

这是最基础的形式:

C
char ch = 'A';
char *p;

p = &ch;

其中:

C
&ch

表示获取 ch 的地址。

所以:

C
p = &ch;

就是把 ch 的地址赋值给字符指针 p。

完整示例:

C
#include 

int main(void)
{
    char ch = 'A';
    char *p = &ch;

    printf("字符:%c
", ch);
    printf("指针指向:%c
", *p);

    return 0;
}

2. 指向字符数组

字符指针还可以指向字符数组的第一个元素:

C
char str[] = "Hello";
char *p = str;

这里不需要写:

C
char *p = &str;

因为数组名 str 在大多数表达式中会自动转换为指向第一个元素的指针,即:

C
str

可以理解为:

C
&str[0]

因此:

C
char *p = str;

实际上让 p 指向:

H
e
l
l
o

↑
p

通过指针可以访问字符串:

C
printf("%s
", p);

也可以访问单个字符:

C
printf("%c
", *p);
printf("%c
", *(p + 1));

输出分别为:

H
e

3. 指向字符串字面量

还可以这样声明:

C
char *p = "Hello";

这段代码在语法层面通常可以通过编译,但需要特别注意:不能通过 p 修改字符串字面量。

例如:

C
char *p = "Hello";
p[0] = 'h';

这种写法会产生未定义行为。

更安全、更明确的写法是:

C
const char *p = "Hello";

此时 p 表示指向不可通过该指针修改的字符数据:

C
const char *p = "Hello";

printf("%s
", p);

如果确实需要修改字符串内容,应使用字符数组:

C
char str[] = "Hello";
str[0] = 'h';

printf("%s
", str);

输出:

hello

四、char *与char的区别

很多初学者容易混淆:

C
char ch;
char *p;

这两个变量虽然都和字符有关,但用途完全不同。

char ch 保存字符数据:

C
char ch = 'A';

而 char *p 保存地址:

C
char *p = &ch;

可以通过下面的代码直观理解:

C
char ch = 'A';
char *p = &ch;

此时:

C
ch

表示字符本身。

C
&ch

表示字符变量的地址。

C
p

保存这个地址。

C
*p

表示访问这个地址对应的字符。

因此四者的含义分别是:

表达式含义
ch字符变量的值
&ch字符变量的地址
p指针保存的地址
*p指针指向的字符

五、char指针赋值时的类型匹配

指针赋值必须关注类型。

例如:

C
char ch = 'A';
char *p = &ch;

类型完全匹配。

而下面这种写法则存在类型问题:

C
int num = 100;
char *p = #

&num 的类型是:

C
int *

而 p 的类型是:

C
char *

两者并不匹配。

虽然某些情况下编译器可能只给出警告,但不应该忽略这种问题。通过错误类型的指针访问对象可能导致未定义行为。

如果确实需要处理不同类型的数据,应根据实际数据类型选择对应的指针类型。

六、一次声明多个char指针时的注意事项

C 语言声明语法中,* 属于变量声明符,而不是基础类型的一部分。这一点在一次声明多个变量时非常重要。

例如:

C
char *p1, *p2;

这里 p1 和 p2 都是字符指针。

但下面的代码:

C
char *p1, p2;

只有 p1 是指针,p2 是普通 char 变量。

也就是说:

char *p1

表示 p1 是 char *。

而:

char p2

表示 p2 是 char。

因此,如果需要声明多个字符指针,应该明确写成:

C
char *p1, *p2, *p3;

为了提高代码可读性,实际项目中也可以分别声明:

C
char *p1;
char *p2;
char *p3;

这样不容易产生误解。

七、char指针与字符数组的关系

字符指针和字符数组经常一起使用,但二者不能简单地认为是同一种变量。

例如:

C
char str[] = "Hello";
char *p = str;

str 是字符数组,数组本身拥有实际存储空间。

而 p 是指针变量,它保存的是某个字符对象的地址。

可以执行:

C
p[0] = 'h';

因为 p 指向的是可以修改的字符数组:

h e l l o 

但是下面这种情况不同:

C
char *p = "Hello";

这里 p 指向字符串字面量,不应该通过 p 修改其内容。

因此,在需要修改字符串时,可以优先使用:

C
char str[] = "Hello";
char *p = str;

如果只是读取固定字符串,可以使用:

C
const char *p = "Hello";

八、使用char指针遍历字符串

由于字符串本质上是以 '' 结尾的字符序列,因此字符指针非常适合遍历字符串。

例如:

C
#include 

int main(void)
{
    char str[] = "Hello";
    char *p = str;

    while (*p != '')
    {
        printf("%c
", *p);
        p++;
    }

    return 0;
}

程序会依次读取:

H
e
l
l
o

其中:

C
*p

表示当前字符。

C
p++

表示让指针移动到下一个 char 对象。

由于 p 是 char * 类型,指针每增加 1,就会移动一个 char 对象的距离。

九、char指针与数组下标的对应关系

下面两种访问方式通常具有相同的效果:

C
str[2]

和:

C
*(str + 2)

例如:

C
char str[] = "Hello";

printf("%c
", str[1]);
printf("%c
", *(str + 1));

两次都会访问字符串中的第二个字符:

e

当使用字符指针时,也可以写:

C
char *p = str;

printf("%c
", p[1]);
printf("%c
", *(p + 1));

这说明数组下标和指针运算在 C 语言中存在紧密关系。

十、char指针赋值中的NULL问题

定义指针变量时,如果暂时没有有效的指向对象,可以初始化为 NULL:

C
char *p = NULL;

此时表示:

p 当前不指向有效的char对象

可以进行判断:

C
if (p != NULL)
{
    printf("%c
", *p);
}

不能直接对空指针解引用:

C
char *p = NULL;
printf("%c
", *p);

这种操作会产生未定义行为,实际运行时可能导致程序崩溃。

因此,字符指针在使用前最好确保它已经指向有效对象。

十一、char指针作为函数参数

字符指针在函数参数中也非常常见。

例如:

C
#include 

void printString(const char *str)
{
    printf("%s
", str);
}

int main(void)
{
    char text[] = "Hello C";
    printString(text);

    return 0;
}

函数:

C
void printString(const char *str)

表示函数接收一个指向字符数据的指针,并且函数内部不会通过 str 修改这些字符。

如果函数需要修改传入的字符数组,则可以使用:

C
void changeString(char *str)
{
    str[0] = 'h';
}

调用:

C
char text[] = "Hello";
changeString(text);

此时原数组内容会被修改。

十二、常见错误写法分析

错误一:把字符直接赋给字符指针

C
char *p = 'A';

这里 'A' 是字符常量,而 p 需要的是地址。二者类型不匹配。

如果需要指向字符变量,应写:

C
char ch = 'A';
char *p = &ch;

错误二:把字符串赋值给char变量

C
char ch = "A";

"A" 是字符串字面量,不是单个字符。

正确写法:

C
char ch = 'A';

如果需要保存字符串,则使用:

C
char str[] = "A";

或者:

C
const char *str = "A";

错误三:修改字符串字面量

C
char *p = "Hello";
p[0] = 'h';

这种写法不安全,因为字符串字面量不应被修改。

推荐:

C
char str[] = "Hello";
str[0] = 'h';

或者在只读场景下:

C
const char *p = "Hello";

错误四:忘记初始化指针

例如:

C
char *p;
*p = 'A';

p 没有指向有效的 char 对象,就直接进行解引用,属于危险操作。

正确方式可以是:

C
char ch;
char *p = &ch;

*p = 'A';

十三、char指针声明与赋值的实用总结

常见写法可以归纳为以下几种:

C
char ch = 'A';

表示定义一个字符变量。

C
char *p = &ch;

表示定义字符指针并让它指向 ch。

C
char str[] = "Hello";
char *p = str;

表示让字符指针指向字符数组的首元素。

C
const char *p = "Hello";

表示使用字符指针访问字符串字面量,并明确不通过该指针修改内容。

C
char *p = NULL;

表示暂时没有有效的指向对象。

掌握 char 与 char * 的区别后,再结合 & 取地址和 * 解引用,就能够正确理解大多数字符指针赋值代码。尤其需要牢记:普通 char 保存的是字符数据,char * 保存的是地址;字符常量使用单引号,字符串使用双引号;需要修改字符串时,应优先使用字符数组,而不是直接修改字符串字面量。