Home php教程 PHP开发 Character arrays and character pointers

Character arrays and character pointers

Dec 12, 2016 pm 05:16 PM
string array

问题1:

字符数组名可以作为左值吗?当然不行

比如 

char str[20] = {'h','e','l','l','o',' ','w','o','r','l','d'};

str++;

不可以这么干,因为字符数组名是一个常量指针,也就是是一个const char*

#include <stdio.h>

int main()
{
    char str[20] = {&#39;h&#39;,&#39;e&#39;,&#39;l&#39;,&#39;l&#39;,&#39;o&#39;,&#39; &#39;,&#39;w&#39;,&#39;o&#39;,&#39;r&#39;,&#39;l&#39;,&#39;d&#39;};
    printf("sizeof(str): %d\n",sizeof(str));
    printf("str: %s\n",str);
    str = str + 1;  //error
    return 0;
}
Copy after login

运行结果如下:

Character arrays and character pointers

当数组名为左值时,它的类型是字符数组;当数组名为右值时,它的数据类型是字符指针。

#include <stdio.h>
#include <string.h>
int main(void)
{
    char buf[10];
    char *p= “afdal”;
    buf = p;  //将一个char* 赋给一个char[10],类型不一样,必然不成功
    printf(“the buf is:%s\n”,buf);
    return 0;
}
Copy after login

问题2:

字符数组如何进行初始化?

#include <stdio.h>

int main()
{
    char ptr[20] = "hello world";  //success
    char str[20] = {&#39;h&#39;,&#39;e&#39;,&#39;l&#39;,&#39;l&#39;,&#39;o&#39;,&#39; &#39;,&#39;w&#39;,&#39;o&#39;,&#39;r&#39;,&#39;l&#39;,&#39;d&#39;};  //success
    char ctr[20];
    ctr = "hello world";  // error: incompatible types when assigning to type ‘char[20]’ from type ‘char *’
    return 0;
}
Copy after login

在给字符数组初始化的时候,会自动在字符数组的结尾加上'\0'

#include <stdio.h>

int main()
{
    char str[20] = {&#39;h&#39;,&#39;e&#39;,&#39;l&#39;,&#39;l&#39;,&#39;o&#39;,&#39; &#39;,&#39;w&#39;,&#39;o&#39;,&#39;r&#39;,&#39;l&#39;,&#39;d&#39;};
    printf("sizeof(str): %d\n",sizeof(str));
    printf("str: %s\n",str);
    int i = 0;
    while(*(str + i) != &#39;\0&#39;)  //判断是否加上&#39;\0&#39;
    {
        printf("%c\n",*( str + i++));
    }
    return 0;
}
Copy after login

运行结果如下:

Character arrays and character pointers

问题3:

字符数组越界访问能编译通过吗?

字符数组越界访问编译可以通过,没有报错,这样会出现很多的问题

#include <stdio.h>

int main()
{
    char str[12] = {&#39;h&#39;,&#39;e&#39;,&#39;l&#39;,&#39;l&#39;,&#39;o&#39;,&#39; &#39;,&#39;w&#39;,&#39;o&#39;,&#39;r&#39;,&#39;l&#39;,&#39;d&#39;};
    printf("%c\n",str[100]);
    return 0;
}
Copy after login

Character arrays and character pointers

打印为空

问题4:

字符数组和字符指针又有什么区别呢?

首先在内存的中位置不同,字符数组保存的字符串存放在内存的栈中,而字符指针指向的字符串保存在内存的静态存储区中。

其次字符数组保存的字符串属于字符串变量,可以被修改,而字符指针指向的字符串是属于字符串常量,不能被修改。

#include <stdio.h>

int main()
{
    char str[12] = {&#39;h&#39;,&#39;e&#39;,&#39;l&#39;,&#39;l&#39;,&#39;o&#39;,&#39; &#39;,&#39;w&#39;,&#39;o&#39;,&#39;r&#39;,&#39;l&#39;,&#39;d&#39;};
    char* ptr = "hello world";
    str[0] = &#39;f&#39;;
    ptr[0] = &#39;f&#39;;  //将字符指针指向的字符串修改,将出现段错误,因为该内存地址只读,因为该字符串属于常量
    return 0;
}
Copy after login

运行结果:

Character arrays and character pointers

段错误是指访问的内存超出了系统给这个程序所设定的内存空间,例如访问了不存在的内存地址、访问了系统保护的内存地址、访问了只读的内存地址等等情况。

#include <stdio.h>

int main()
{
    char* ptr = "hello world";
    ptr[11] = &#39;!&#39;;  //往常量字符串末尾添加字符,相当于连接两个字符串,出错
    ptr[12] = &#39;\0&#39;;
    return 0;
}
Copy after login

这样也会出现段错误。

问题5:

字符指针是不是和字符数组名都是指针常量呢?

不是,字符指针,可以改变它的指向,也就是可以为左值。可以将一个字符指针指向一个字符串常量后又指向另外一个字符串常量。字符指针在为初始化之前,他是一个未定义的值,将指向任何可能的地方,所以在使用字符指针时一定要注意初始化。

#include <stdio.h>

int main()
{
    char* ptr;
    printf("ptr: %c\n",*ptr);
    return 0;
}
Copy after login

运行结果:

编译可以通过,但是ptr指向的内存地址是任意的

当然也可以将一个字符指针指向一个字符数组。

#include <stdio.h>

int main()
{
    char str[12] = {&#39;h&#39;,&#39;e&#39;,&#39;l&#39;,&#39;l&#39;,&#39;o&#39;,&#39; &#39;,&#39;w&#39;,&#39;o&#39;,&#39;r&#39;,&#39;l&#39;,&#39;d&#39;};
    char* ptr = str;
    printf("ptr: %s\n",ptr);
    return 0;
}
Copy after login

运行结果:

Character arrays and character pointers

问题6:

如果一个字符指针指向一个堆中动态内存。那么我们如何初始化该内存中的值?

#include <stdio.h>
#include <stdlib.h>

int main()
{ 
    char* str = (char*)malloc(sizeof(char)*20);
    printf("str:%p\n",str);     //str在堆中内存首地址
    str = "hello world";
    printf("str:%p\n",str);    //str在静态存储区内存首地址
    char* ptr = "I love you";
    printf("ptr:%p\n",ptr);    //str在静态存储区内存首地址
    return 0;
}
Copy after login

运行结果如下:

Character arrays and character pointers

很明显前后的地址不一样,前一个指向堆中的内存的地址,而后一个指向了静态存储区中的内存的地址。我本以为我通过上述方式进行初始化str的时候,我可以将堆中内存进行初始化,我发现我错了,字符指针将被重新指向。但是我想如果我们将str声明为const呢?那将会出现什么样的结果呢?

#include <stdio.h>
#include <stdlib.h>

int main()
{ 
    const char* str = (char*)malloc(sizeof(char)*20);  //我以为const将修饰str,使得str不能再作为左值而出现,我错了,const修饰的是由str指向的字符串,
    printf("str:%p\n",str);                            //该字符串不能再被修改
    str = "hello world";
    printf("str:%p\n",str);  
    return 0;
}
Copy after login

运行结果:

Character arrays and character pointers

如果我们将上述的代码做如下修改,程序还能编译通过吗?

#include <stdio.h>
#include <stdlib.h>

int main()
{ 
    const char* str = (char*)malloc(sizeof(char)*20);
    printf("str:%p\n",str);
    str[0] = &#39;h&#39;;    //这种赋值才是对str原来所指向的堆中的内存的赋值,编译不过,因为str指向的堆中的内存是只读的。
    str = "hello world";     
    printf("str:%p\n",str);
    return 0;
}
Copy after login

运行结果如下:

Character arrays and character pointers

上述就引发了我思考为什么const修饰的是str指向的字符串,而不是str本身呢?

原来,char* const str才是真正的修饰str本身,使得str为只读的,不能再被修改,也就是重新指向其他内存地址。而const char* str 和 char const* str 的意义是一致的,都是修饰的是*str。

#include <stdio.h>
#include <stdlib.h>

int main()
{ 
    char* const str = (char*)malloc(sizeof(char)*20);
    printf("str:%p\n",str);
    str[0] = &#39;h&#39;; 
    str = "hello world";      //变量str被重新指向,error,编译不过
    printf("str:%p\n",str);
    return 0;
}
Copy after login

运行结果如下:

Character arrays and character pointers

那么我们又该如何初始化一个字符指针指向的内存呢?

其实我们可以很清楚的分析,如果str是一个字符指针,也就是一个变量,变量是可以被重新赋值的,而每一个字符串本身是有一个地址的,str = “hello world”,必然就是改变了str的值,使得str保存着"hello world"的内存首地址,而一旦你将str = "I love you",必然str将保存这"I love you"的内存首地址,这都是毋庸置疑的。

#include <stdio.h>

int main()
{
    printf("hello world:%p\n","hello world");   //将打印出"hello world"的内存地址
    printf("I love you:%p\n","I love you");    //将打印出"I love you"的内存地址
    return 0; 
}
Copy after login

运行如下:

Character arrays and character pointers

下面我得回到这样一个问题?

str 和 *str的区别,很明显,str是一个指针,而*str是str指向的内存的存放的值,既然我们想改变str指向内存中的值,既*str的值,那么为何不将*str作为左值,来初始化str所指向内存的值呢?而*str 不就是 str[0]吗?所以很明显了。上述问题:那么我们又该如何初始化一个字符指针指向的内存呢?当然这个仅限于字符指针指向的是由mlloc分配的堆中的内存以及字符数组指向的栈中的内存。而字符指针如果指向字符常量,不可修改字符指针指向的内存的值,因为字符常量是只读的。

#include <stdio.h>
#include <stdlib.h>

int main()
{ 
    char* const str = (char*)malloc(sizeof(char)*20);
    printf("str:%p\n",str);
    str[0] = &#39;A&#39;;     //数组下标型赋值
    *(str + 1) = &#39;l&#39;;  //指针++型赋值
    str[2] = &#39;e&#39;,
    *(str + 3) = &#39;x&#39;;
    printf("str:%s\n",str);  
    printf("str:%p\n",str);
    return 0;
}
Copy after login

运行如下:

Character arrays and character pointers

#include <stdio.h>
#include <stdlib.h>
int main()
{ 
    char str[20]; 
    printf("str:%p\n",str);
    str[0] = &#39;A&#39;; 
    *(str + 1) = &#39;l&#39;;
    str[2] = &#39;e&#39;,
    *(str + 3) = &#39;x&#39;;
    //str[4] = &#39;\0&#39;;  //当我们没有手动给字符串结尾附上&#39;\0&#39;
    printf("str:%s\n",str);
    printf("str:%p\n",str);
    return 0; 
}
Copy after login

运行如下:

Character arrays and character pointers

上述的运行结果说明上述程序并没有自动给字符串结尾附上'\0',对于字符数组除非这样赋值,str[20] = "hello world",不然你就得手动给字符串附上字符串结尾'\0'。

#include <stdio.h>
#include <stdlib.h>

int main()
{ 
    char str[20]; 
    printf("str:%p\n",str);
    str[0] = &#39;A&#39;; 
    *(str + 1) = &#39;l&#39;;
    str[2] = &#39;e&#39;,
    *(str + 3) = &#39;x&#39;;
    str[4] = &#39;\0&#39;;
    printf("str:%s\n",str);
    printf("str:%p\n",str);
    return 0; 
}   
~
Copy after login

运行结果:

Character arrays and character pointers

附上一段我关于memcpy()和memmove()的代码的实现。

#include <stdio.h>
#include <stdlib.h>

void mem_copy(char* const dest, const char* const src)
{
    for(int i = 0; *(src + i) != &#39;\0&#39;; i++)
        *(dest + i) = *(src + i);
}

void mem_move(char* const dest, const char* const src)
{
    int i = 0;
    while(*(src + i) != &#39;\0&#39;)
        i++;
    for(; i != -1; i--)
        *(dest + i) = *(src + i);
}

int main()
{
    char* src = "hello world";
    char* const dest1 = (char*)malloc(sizeof(char) * 20);
    char dest2[20];
    mem_copy(dest1,src);
    mem_move(dest2,src);
    printf("dest1:%s\n",dest1);
    printf("dest2:%s\n",dest2);
    return 0;
}
Copy after login

当我们需要将内存的中的某一地址段的内容拷贝到内存中另一地址段中,以上是将字符串常量区的内容拷贝到堆中和栈中,我们可以看到我分别使用了malloc和字符数组,当然我们得考虑可能在拷贝的过程中会有地址段重叠的问题,重叠该怎么拷贝,解决方案很简单,就是从尾向前拷贝,即可。

运行结果如下:

Character arrays and character pointers

以上是我对c语言中字符串操作的一些理解

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
4 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Best Graphic Settings
4 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. How to Fix Audio if You Can't Hear Anyone
4 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Chat Commands and How to Use Them
4 weeks ago By 尊渡假赌尊渡假赌尊渡假赌

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

How to use split() function in oracle How to use split() function in oracle May 07, 2024 pm 01:06 PM

The SPLIT() function splits a string into an array by a specified delimiter, returning a string array where each element is a delimiter-separated portion of the original string. Usage includes: splitting a comma-separated list of values ​​into an array, extracting filenames from paths, and splitting email addresses into usernames and domains.

How to sort strings in java How to sort strings in java Apr 02, 2024 am 02:18 AM

Ways to sort strings in Java: Use the Arrays.sort() method to sort an array of strings in ascending order. Use the Collections.sort() method to sort a list of strings in ascending order. Use the Comparator interface for custom sorting of strings.

What does \0 mean in c language What does \0 mean in c language Apr 27, 2024 pm 10:54 PM

In C language, \0 is the end mark of a string, called the null character or terminator. Since strings are stored in memory as byte arrays, the compiler recognizes the end of the string via \0, ensuring that strings are handled correctly. \0 How it works: The compiler stops reading characters when it encounters \0, and subsequent characters are ignored. \0 itself does not occupy storage space. Benefits include reliable string handling, improved efficiency (no need to scan the entire array to find the end), and ease of comparison and manipulation.

What does args mean in java What does args mean in java Apr 25, 2024 pm 10:15 PM

args stands for command line arguments in Java and is an array of strings containing the list of arguments passed to the program when it is started. It is only available in the main method, and its default value is an empty array, with each parameter accessible by index. args is used to receive and process command line arguments to configure or provide input data when a program starts.

What does args mean in java What does args mean in java May 07, 2024 am 02:24 AM

args is a special parameter array of the main method in Java, used to obtain a string array of command line parameters or external input. By accessing the args array, the program can read these arguments and process them as needed.

Application of artificial intelligence technology in PHP functions Application of artificial intelligence technology in PHP functions May 01, 2024 pm 01:15 PM

AI technology has been combined with PHP functions to enhance the functionality of the application. Specific AI applications include: using machine learning algorithms to classify text, such as Naive Bayes. Perform in-depth text analysis using natural language processing techniques such as word segmentation and stemming.

How to sort Chinese characters in C language environment? How to sort Chinese characters in C language environment? Feb 18, 2024 pm 02:10 PM

How to implement Chinese character sorting function in C language programming software? In modern society, the Chinese character sorting function is one of the essential functions in many software. Whether in word processing software, search engines or database systems, Chinese characters need to be sorted to better display and process Chinese text data. In C language programming, how to implement the Chinese character sorting function? One method is briefly introduced below. First of all, in order to implement the Chinese character sorting function in C language, we need to use the string comparison function. Ran

What impact do C++ functions have on program performance? What impact do C++ functions have on program performance? Apr 12, 2024 am 09:39 AM

The impact of functions on C++ program performance includes function call overhead, local variable and object allocation overhead: Function call overhead: including stack frame allocation, parameter transfer and control transfer, which has a significant impact on small functions. Local variable and object allocation overhead: A large number of local variable or object creation and destruction can cause stack overflow and performance degradation.

See all articles