1. Указатели на символы и массивы символов

Указатель на символ

Сама переменная-указатель на строку — это переменная, используемая для хранения начального адреса строки. Сама строка хранится в непрерывной области памяти, начинающейся с этого начального адреса, и заканчивается\0как конец строки.

char *ps="C Language";

означает 10 элементов в первом измерении и 20 элементов во втором измерении, причем значения хранятся в непрерывной области памяти, без указателей.

char *ps;  // ps 字符串指针,是指针,是一个变量

ps="C Language"; // ps — это начальный адрес строки. Используйте ps++ для обхода строки. Строка хранится в непрерывной области памяти, начиная с ps, и заканчивается\0как конец строки.

Здесь нужно четко рассмотреть два момента:

1. *a просто указывает на символ.

Пример выглядит следующим образом:

Пример

#include <stdio.h> #include <stdlib.h> int main(void){ char *a= "bcd" ; printf("Вывод символа: %c\n", *a); /*Чтобы вывести символ, используйте "%c"*/ printf("Вывод символа: %c\n", *(a+1) ); /*Чтобы вывести символ, используйте "%c"*/ printf("Вывод строки: %s\n", a); /*Чтобы вывести строку, используйте "%s"; также не должно быть звездочки "*" перед a.*/ system("pause"); /*Чтобы увидеть результат вывода*/ }

Результат выполнения выглядит следующим образом:

输出字符:b 
输出字符:c 
输出字符串:bcd 

2. Если строковая константа появляется в выражении, её значение представляет собой адрес первого символа этой строковой константы. Так что "hello" всего лишь представляет свой адрес. Исходное объявление эквивалентно следующему объявлению:

char *a;  
a="hello"; /*这里字符串"hello"仅仅代表其第一个字符的地址*/

Символьный массив

Символьный массив состоит из нескольких элементов массива и может использоваться для хранения целой строки. (То есть используйте символьный массив для хранения строки.)

В C строки рассматриваются как символьные массивы. (Не в C++.)

Способы инициализации символьного массива:

1). Символьный массив можно инициализировать строковой константой:

char  str[]={"Iamhappy"};

Фигурные скобки можно опустить.

char  str[]="Iamhappy";  # 系统自动加入 \0 

Примечание: Приведённое выше присваивание всего массива можно использовать только при инициализации символьного массива, а не для присваивания символьному массиву. Присваивание символьному массиву можно выполнять только поэлементно.

Следующий способ присваивания неверен:

char str[20];
str="Iamhappy";

Присвойте значения каждому элементу символьного массива по одному.

char str[10]={'I','','a','m','','h','a','p','p','y'};

В C есть два способа представления и хранения строк:

(1) Использовать символьный массив для хранения строки

char str[]="IloveChina";

(2) Использовать указатель на символ для указания на строку

char *str="IloveChina";

Оба способа представления используют следующее для вывода строк:printf("%s\n", str);

%sЧтобы вывести строку, укажите имя переменной-указателя на символ str (для первого представления имя символьного массива — это начальный адрес символьного массива, что имеет тот же смысл, что и указатель во втором). Система сначала выводит символьные данные, на которые он указывает, затем автоматически увеличивает str на 1, чтобы указать на следующий символ... и так далее, пока не будет встречен терминатор строки.\0 。


2. Указатели на строки

string* strМожно присвоить:

string* str = {"hello", "world"}; 
//  对比与 char *name = "wang" = {'w','a','n','g'}
//  *(str) = "hello", *(str+1) = "world"
//  *(*(str)+1) = 'e'

То есть каждый элемент имеет тип string, что отличается от char*. Однако string* можно заменить на char**:

string = char*, string* = char**

3. Массивы указателей на строки

Пример

#include <stdio.h> void main() { ear *str[] = {"Hello", "C++", "World"}; //char (*str)[] = ... int i; for(i=0; i<3; i++) printf("%s\n", str[i]); } // str // str // str

или

#include <stdio.h> #include <string.h> int main() { char *str[] = {"Hello", "C++", "World"}; char **p; for(p=str; p<str+3; p++) puts(*p); #*p— адрес начала строки, *p[0]— адрес первого символа строки.}

Пример

#include<stdio.h> #include<stdlib.h> int main() { char *str[3]={"Hello","C++","World"}; printf("%s,%s,%c",str[0],str[0]+1,*(*(str+2)+1)); system("pause"); }

Результат:

Hello,ello,o

Формат:char* na[N] = {"li", "zh", "li", "zh", "li"};

char *a[]: обозначает, что a — это массив, элементы которого являются указателями на тип char (все элементы массива хранятся в непрерывной памяти). Имя массива — это адрес памяти первого байта массива, и имя массива a также представляет указатель. Поэтому a представляет не содержимое, хранящееся по адресу a, а сам адрес a.

a+1: представляет адрес памяти второго элемента a, поэтому добавляет 8 байт. (Поскольку элементы a — это указатели char, которые требуют 8 байт (64-битный адрес памяти).)

*(a+1): обозначает содержимое второго элемента массива a (который является указателем char, представленным как адрес строки "world" в этом примере).

*(*(a+1)): обозначает содержимое (символ w), на которое указывает содержимое (указатель char) второго элемента массива a.

char * a[10]: означает, что этот массив может содержать не более 10 элементов (указателей на char), то есть массив занимает 10*8 = 80 байт.

#w:        a+1   =>   *(a+1)  =>   *(a+1)[0]
           指针(地址)   指针内容(字符串)      字符

четыре

char *argv:理解为字符串
char **argv:理解为字符串指针
char *argv[]:字符串指针数组

int main(int argc, char*argv[])Это типичный пример использования имени массива (или массива указателей) в качестве параметра функции; это также формальный параметр-массив без указанного размера.

Иногда, чтобы обрабатывать элементы массива в вызываемой функции, можно задать дополнительный формальный параметр для передачи количества обрабатываемых элементов массива. Более того, когда имя массива используется как фактический параметр, формальному параметру передаётся не значение элементов массива, а адрес первого элемента массива фактического параметра, так что оба массива используют одну и ту же область памяти. Это отличается от использования переменных в качестве параметров функции.

Можно посмотреть примеры массивов как параметров функций и массивов указателей как формальных параметров функции main. В книге Тан Хаоцяна это объясняется очень подробно.

1. Когда char [] используется как параметр функции, это означает char *. При передаче в качестве параметра функции фактически копируется адрес первого элемента массива.

Таким образом, void test(char a[]) эквивалентно void test(char *a)

 char x[10] ;

Тогда вызов test(x) эквивалентен присваиванию адреса первого элемента x параметру a.

2. char *a и char a[]

  • Сходство: a — указатель, указывающий на тип char.
  • Различие: char a[] хранит содержимое в стеке. char *a хранит указатель в стеке, а содержимое — в константах.

3. char *a

  • Сходство: a в обоих случаях является указателем второго уровня; *a представляет указатель первого уровня; **a представляет содержимое, хранящееся в памяти.
  • Различие: char *a

4. Подсказка: количество [] и * соответствует. Например, char a[][] имеет 2 уровня указателей, что эквивалентно char **a; char *a[] — то же самое, два уровня указателей. Если запутались, посчитайте, сколько есть * и [], и вы узнаете, хранится ли содержимое или адрес. Например, в случае char a[][]: &a, a, *a — все являются адресами, а **a — содержимым.

Исходный URL: https://www.cnblogs.com/cj2014/p/3726380.html