2018年8月29日水曜日

C言語 ポインタ宣言の読み方

2016 Dec. 25.

http://kmaebashi.com/programmer/pointer.html 参照方。
 
( http://news.mynavi.jp/articles/2008/04/18/pointer/002.html より)
char *ap[3];
  あるapという名前のものがある
    ↓
    apは配列の先頭アドレスを表す定数で、配列要素ap[x]を求めることができる
    ↓
    ap[x]はポインタであり、その指し示す先の「*ap[x]」はchar型である
    以上により、「char *ap[3];」が「ポインタの配列」を宣言している

char **pp;     ← 「char型へのポインタ」へのポインタppを宣言
  char *ap[3];   ← 「char型へのポインタ」を要素とする配列ap(要素数3)を宣言
  char a[5];     ←  char型を要素とする、要素数5の配列aを宣言

ap[2] = a;                    ← ap[2](ポインタ)にaのアドレス定数を代入
a[3] = 'Y';                   ← a[3]には文字'Y'を代入
pp = ap;                      ← apのアドレス定数はポインタのポインタに代入可
printf("%c\n", ap[2][3]);     ← apに[ ]の添字を2つ付けて内容を読む
printf("%c\n", pp[2][3]);     ← ppを使っても同様に記述できる
printf("%c\n", *(*(ap+2)+3)); ← ポインタとして記述する場合はこうなる
printf("%c\n", *(*(pp+2)+3)); ← ppを使う場合も同様
printf("%c\n", *(ap[2]+3));   ← 添字の[ ]とポインタの*が混在した記述も可能
printf("%c\n", *(pp[2]+3));   ← ppを使う場合も同様
printf("%c\n", (*(ap+2))[3]); ← 添字の[ ]とポインタの*を入れ替えた場合
printf("%c\n", (*(pp+2))[3]); ← もちろんppを使っても同様
 
( http://news.mynavi.jp/articles/2008/04/18/pointer/003.html より)
「配列へのポインタ」の宣言の「char (*pa)[5];」は、次のように考えます。

     あるpaという名前のものがある
     ↓
     paはポインタであり、paが指し示す先(*pa)は、何らかの要素数5の配列全体である
     ↓
    その配列の各要素「(*pa)[x]」はchar型である
    「配列へのポインタ」は、単に配列の先頭アドレスを指したポインタではありません。このポインタ(pa)は所定の大きさの配列全体を指しており、paをインクリメントすると、paが指し示す配列のサイズ分(5バイト)、アドレス値が加算されます。このため、pa自体はポインタであっても、宣言時にはそのポインタの指し示す先の配列の大きさを指定する必要があります。
    なお、paの宣言では、[5]という値を指定していますが、実際の配列用のメモリは(宣言しただけでは)確保されません。

( http://blog.tojiru.net/article/426537111.html より )
日本語らしくしたい場合は、最後に順番をひっくり返します。

(1) 識別子を探す。

(2) 識別子の両隣から読み始めるが、次の順番で結合される。
  1. 優先度を表す()
  2. 関数を表す()、配列を表す[]
  3. ポインタを表す*
(3) 配列はarray(要素数) of ...
      関数はfunction(引数) returning ...
      ポインタはpointer to ...
      という風に英語で置き換えてゆく。

(4) 最後に派生元の型(intとかfloatとか)を付けて終わり。

  *a[10]*a(void)みたいに両側に何か書いてある時は、配列や関数の方が勝つ。

 int (*(*a(void))[10])(void);
   a is function(void) returning pointer to array(10) of pointer to function(void) returning int.
   aは、int を返す関数(void) へのポインタ の配列(要素数10) へのポインタ を返す関数(void)
 
 void (*signal(int, void (*)(int)))(int);
   signal is function(int, pointer to function(int) returning void) returning pointer to function(int) returning void.
   signalは、void を返す関数(int) へのポインタ を返す関数(int, voidを返す関数(int) へのポインタ) 


( https://naofumi.castle104.com/c%E8%A8%80%E8%AA%9E%E3%81%AE%E3%83%9D%E3%82%A4%E3%83%B3%E3%82%BF%E5%AE%A3%E8%A8%80%E3%81%AE%E8%AA%AD%E3%81%BF%E6%96%B9/ より ) 
  1. 最初は変数名から出発して、型まで
    char *(*(**foo [][8])())[];
    foo ischar
  2. 変数名の右の[]
    char *(*(**foo [][8])())[];
    foo is array of … char
  3. さらに右に行って[8]
    char *(*(**foo [][8])())[];
    foo is array of array of 8 … char
  4. )にぶつかったので、変数名の左のポインタ演算子*を処理
    char *(*(**foo [][8])())[];
    foo is array of array of 8 pointer to … char
  5. さらにその左のポインタ演算子*
    char *(*(**foo [][8])())[];
    foo is array of array of 8 pointer to pointer to … char
  6. ()の中の処理が終わったので、右に移動。そこには関数を表す()があります
    char *(*(**foo [][8])())[];
    foo is array of array of 8 pointer to pointer to function returning … char
  7. ここで)にぶつかるので、左に戻ってポインタ演算子*を処理
    char *(*(**foo [][8])())[];
    foo is array of array of 8 pointer to pointer to function returning pointer to … char
  8. 左に行くと(にぶつかるので、この()は処理が終了。次に右に行って[]を処理
    char *(*(**foo [][8])())[];
    foo is array of array of 8 pointer to pointer to function returning pointer to array of … char
  9. これで右端まで行ったので、左に戻って一番左のポインタ演算子*を処理
    char *(*(**foo [][8])())[];
    foo is array of array of 8 pointer to pointer to function returning pointer to array of pointer to char


2018年8月26日日曜日

NVIDIA Corporation GF108 [GeForce GT630]のドライバのubuntu系へのインストール

2018 Sep. 02.
2018 Aug. 26.

# apt install nvidia-352

大画面表示になったので 、表示フォントを3ポイント上げた。

2018年8月19日日曜日

BitbucketへのSSH認証導入

2018 Aug. 19.
 
$ cd ~/.ssh
$ mkdir bitbucket
$ cd bitbucket
$ ssh-keygen -t rsa -C YourMail@Address
 Enter file in which to save the key の問いに ~/.ssh/bitbucket/id_rsa と入力する。
 パスワードの設定を2回問われるが、Enterのみを入力する。
  
$ mv id_rsa id_rsa.bitbucket
$ chmod 600 id_rsa.bitbucket

~/.ssh/config に次を記載する
 Host bitbucket.org
  HostName bitbucket.org
  IdentityFile ~/.ssh/bitbucket/id_rsa.bitbucket
  User git
  Port 22
  TCPKeepAlive yes
  IdentitiesOnly yes
 
https://bitbucket.org にアクセスし、
「Manage Account」→「SSH keys」→「Add Key」と鍵設定画面に移る。
 Label:任意の文字列(クライアントデバイス名とか)
 Key:「id_rsa.bitbucket.org.pubの内容(メールアドレスを含む)」コピー&ペースト
 「鍵追加」ボタンを押す。

接続テスト
$ ssh -T git@bitbucket.org
(表示) 
 conq: logged in as ユーザ名.
You can use git or hg to connect to bitbucket. Shell access is disabled.
 
それまでhttps/sslで認証していたリポジトリは削除して再クローンを要するみたい。
 

ruby 配列を値とするハッシュ

2018 Aug. 19.


http://simanman.hatenablog.com/entry/2013/09/24/211044

  list = Hash.new{|hash, key| hash[key] = []}
  Hash.newにブロックを与えるとブロック引数の1番目がhash自身、2番目がkeyとなります。
  そこで上記のように配列を定義してあげると、keyごとに配列を初期化することが出来るようになります。

  RubyはHashのデフォルト値をHash.newの引数として渡すことで実現できますが、配列を渡すと同じ参照になってしまうのでうまくいきません。
    失敗例:list = Hash.new([])

2018年8月18日土曜日

ruby Could not locate Gemfile or .bundle/ directory スクリプトのファイル属性を実行可能に

2018 Aug. 18.

rubyスクリプトを起動すると
Could not locate Gemfile or .bundle/ directory
で止まった。

Bundler設定を疑ったが、単にファイル属性に実行可能属性が無いだけだった。

2018年8月17日金曜日

git ブランチの統合

2018 Aug. 17.

devブランチのmasterブランチへの統合

(現在のブランチを確認する)
$ git branch

(devブランチに移る)
$ git checkout dev

(devブランチを最新に)
$ git fetch origin dev
$ git merge FETCH_HEAD

(masterブランチにチェック移る)
$ git checkout master

(masterブランチを最新に)
$ git fetch origin master
$ git merge FETCH_HEAD

(devブランチをmasterブランチに統合)
$ git merge dev

git ブランチの削除

2018 Aug. 17.

ローカルブランチの削除
$ git branch -d BRANCH

リモートブランチの削除
$ git push --delete origin BRANCH

2018年8月15日水曜日

シェルスクリプト テキストファイルを行の文字数順にソート

2018 Aug. 15.

$ cat TextFile | awk '{print length() ,$0}' | sort -n | awk '{$1 = ""; print}'
    各行の先頭にその行の文字数を書き込み、その数値でソートした後に、awkの$1 = "" によって文字数の数値を削除している。

2018年8月14日火曜日

git ローカルに無いリモートのブランチのローカルへのチェックアウト

2018 Aug. 14.

 リモートとローカルのブランチ一覧を表示
 $ git fetch
$ git branch -a

 リモートのorigin/BRANCHをローカルBRANCHにチェックアウトする
$ git checkout -b BRANCH origin/BRANCH
 
 
 

xfceのパネルにプログラム起動アイコンを入れる

2018 Aug. 14.

パネルを右クリックして「パネル」>「新しいアイテムの追加」を選択

「ランチャ」を選択して「追加」ボタンをクリック

「新しいアイテムの追加」ウィンドウは閉じる

パネルに置かれたランチャを右クリックして「プロパティ」を選択

新規追加のボタンをクリック

 ランチャを作成する

2018年8月13日月曜日

ubuntu系linuxインストール

2019 Oct. 14.
2019 Jan. 04.
2018 Dec. 01.
2018 Nov. 04.
2018 Oct. 14.
2018 Oct. 12.
2018 Aug. 13.
(install) DVDからlinuxディストリビューションをインストール
(video)  nvidia-xxxインストール
(user) グループ、ユーザ設定
(network) IPアドレス設定(dhcpから固定アドレスに変更)
(network) /etc/hosts設定
(TCP Wrapper) /etc/hosts.deny /etc/hosts.allow 基本設定
sshサーバー
  ポート設定
    ssh設定ファイル
  TCP Wrapper設定(/etc/hosts.deny /etc/hosts.allow)
  netfilter設定(ufw)
(nfs server)(nfs client) portmap rpcbind nfs-commonインストール
(file system) fstab設定
システムワイドパス設定
ユーザーのumask設定
sshクライアント
時刻合わせ
anti-virusソフトインストール
  Sophos Anti-Virus for Linux

プリンタインストール
ルータ ポート転送設定
sambaインストール
OpenVPNインストール
javaインストール
    # apt install default-jdk
mysqlインストール
phpインストール
apache2インストール
  80番ポート開放状況を確認する(ufw status)
pt2・recpt1インストール
epgrec_unaインストール
tssplitter_lite, ffmpegインストール
gitインストール bitbucket設定
rbenv ruby bundlerインストール
grive2インストール
rootユーザーcron設定
一般ユーザーcron設定
 cronでのPATH, HOME, RUBYLIB等を設定
sinatraインストール・設定
mysqlデータ移行
wol設定
RTMPサーバーインストール

2018年8月1日水曜日

シェルスクリプト 空白を含む文字列を格納した変数の展開

2018 Nov. 11.
2018 Aug. 01.

Str=' ab     cd '

COMMAND $Str
シェル展開により
COMMAND  ab     cd 

echo $Str
シェル展開により
echo  ab     cd
    出力 'ab cd'  ( ' は出力に含まない)
     Strの先頭と末尾の空白が落ちる。abとcdの間の空白は1つになる。

cp $Str
シェル展開により
cp  ab     cd 
 (ファイルabのファイルcdへのコピー)


COMMAND "${Str}"
シェル展開により
COMMAND ' ab     cd '

echo "${Str}"
シェル展開により
echo ' ab     cd '
    出力 ' ab     cd '  ( ' は出力に含まない)
      Strの先頭と末尾の空白が残る。abとcdの間の空白もすべて残る。

cp "${Str}"
シェル展開により
cp ' ab     cd '
 (ファイル「 ab     cd 」のコピー先が指定されていない)